From 2b751de35236a6f89a96bce16b870bebc57fe5bf Mon Sep 17 00:00:00 2001 From: DMA <105755300+DDMMMAA@users.noreply.github.com> Date: Mon, 4 Nov 2024 15:50:08 -0500 Subject: [PATCH 001/125] Add files via upload --- project blueprint draft i guess.docx | Bin 0 -> 19657 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 project blueprint draft i guess.docx diff --git a/project blueprint draft i guess.docx b/project blueprint draft i guess.docx new file mode 100644 index 0000000000000000000000000000000000000000..6f135ddacaee90204b5bf2682d9420488f2bead4 GIT binary patch literal 19657 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 Gf_MO}$1nQ; literal 0 HcmV?d00001 From 9a006f0fe8980e7851650f280d3a9f7de49a85ad Mon Sep 17 00:00:00 2001 From: DMA <105755300+DDMMMAA@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:08:37 -0500 Subject: [PATCH 002/125] Update specification of blue print to README.md --- README.md | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 5e1d8b77c..513c02bed 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,9 @@ -# Note Application +# Chess Puzzles -This is a minimal example demonstrating usage of the -password-protected user part of the API used in lab 5. - -You can find more information about the API endpoints in -[the documentation](https://www.postman.com/cloudy-astronaut-813156/csc207-grade-apis-demo/documentation/fg3zkjm/5-password-protected-user). - -If your team is considering an application for which it would be convenient to -store data in something like a database, you may find that the API calls demonstrated -here will be useful in your project, as this will allow you to store -an arbitrary JSON object associated with a username and password. - -In this application, a single note has a name (the "username" in terms of the API) and the note -can be read by anyone who knows the name — but only edited by someone who -knows the password for it. - -You can see the documentation in the various files for more information. +The domain will be able to generate random chess puzzles with options for daily, random puzzles, or specifically themed puzzles. +A user will be able to view their puzzle statistics or review past puzzles within the current session of the program. +Users should have the option to log in or create an account [built into the lichess api]. +If a user is logged in, they should be able to access any past puzzle scores or game histories they’ve played on that account ## Testing From f178b9c6d9b5053880d9c37f31a5b4264c7e0823 Mon Sep 17 00:00:00 2001 From: DMA <105755300+DDMMMAA@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:10:40 -0500 Subject: [PATCH 003/125] Update partial UserStories to README.md --- README.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 513c02bed..28a356798 100644 --- a/README.md +++ b/README.md @@ -5,15 +5,11 @@ A user will be able to view their puzzle statistics or review past puzzles withi Users should have the option to log in or create an account [built into the lichess api]. If a user is logged in, they should be able to access any past puzzle scores or game histories they’ve played on that account -## Testing +## User Stories -The repo also includes an example of a use case interactor test, as well as -an example of an end-to-end test which automates button clicks and inspects -the contents of the actual views. This is something we discussed in the lectures -about testing in CA but had not provided a code example of before. Note, one -could also inspect the contents of the ViewModel objects instead when testing -CA to make a similar test which would be less dependent on the details of the -specific UI implementation. +1. John wants to play a chess puzzle. He opens the chess puzzle player and clicks generate puzzle of the day. The chess puzzle of the day loads on screen. [Michelle’s Story] +2. Tom and Tim argued about who is a better chess player, so they decided to compare their Rank point of Ranking system. [Jiaqi Ma’s Story] +3. As Mary hears about this chess puzzle, she wants to create an account and log in to start a puzzle. [Chihana’s Story] ## Project Starter Code From 8676e06d72e3d0f99c2b2f0058e12bc92680a2e1 Mon Sep 17 00:00:00 2001 From: DMA <105755300+DDMMMAA@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:16:36 -0500 Subject: [PATCH 004/125] Update Team members on README.md --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 28a356798..be3460787 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,15 @@ # Chess Puzzles +## Team Members + +Chihana Kashiwabara - unomaru +Jiaqi Ma - DDMMMAA +Michelle Bakman - 207moment +John Ding - J0hnDing +Yann ... + +## Project Domain + The domain will be able to generate random chess puzzles with options for daily, random puzzles, or specifically themed puzzles. A user will be able to view their puzzle statistics or review past puzzles within the current session of the program. Users should have the option to log in or create an account [built into the lichess api]. From e7e56d59eb49a3253e71852d1a5e0fe805e5a4bf Mon Sep 17 00:00:00 2001 From: DMA <105755300+DDMMMAA@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:17:20 -0500 Subject: [PATCH 005/125] formating TeamMembers section of README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index be3460787..8bf9f08c5 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,13 @@ ## Team Members Chihana Kashiwabara - unomaru + Jiaqi Ma - DDMMMAA + Michelle Bakman - 207moment + John Ding - J0hnDing + Yann ... ## Project Domain From c162887c4efe113c56597bce39758fc2a9b0ca4a Mon Sep 17 00:00:00 2001 From: DMA <105755300+DDMMMAA@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:19:23 -0500 Subject: [PATCH 006/125] Update Yann and John's user story on README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8bf9f08c5..fdec24fa1 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Michelle Bakman - 207moment John Ding - J0hnDing -Yann ... +Yann Chi - ... ## Project Domain @@ -24,6 +24,8 @@ If a user is logged in, they should be able to access any past puzzle scores or 1. John wants to play a chess puzzle. He opens the chess puzzle player and clicks generate puzzle of the day. The chess puzzle of the day loads on screen. [Michelle’s Story] 2. Tom and Tim argued about who is a better chess player, so they decided to compare their Rank point of Ranking system. [Jiaqi Ma’s Story] 3. As Mary hears about this chess puzzle, she wants to create an account and log in to start a puzzle. [Chihana’s Story] +4. Andy is learning chess, and his teacher use this program to measure Andy’s skill level, and to trend his improvement through a long period utilizing the ranking system. [Yann Chi's Story] +5. Felix wants to see the possible moves he can make with one piece, so he click on that piece and the possible cells will be indicated. [John’s Story] ## Project Starter Code From c1a9e44e15bfda243e618504d813eb25ac9190a7 Mon Sep 17 00:00:00 2001 From: DMA <105755300+DDMMMAA@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:21:20 -0500 Subject: [PATCH 007/125] delete instruction from course repo on README.md --- README.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/README.md b/README.md index fdec24fa1..8aa071e6b 100644 --- a/README.md +++ b/README.md @@ -26,11 +26,3 @@ If a user is logged in, they should be able to access any past puzzle scores or 3. As Mary hears about this chess puzzle, she wants to create an account and log in to start a puzzle. [Chihana’s Story] 4. Andy is learning chess, and his teacher use this program to measure Andy’s skill level, and to trend his improvement through a long period utilizing the ranking system. [Yann Chi's Story] 5. Felix wants to see the possible moves he can make with one piece, so he click on that piece and the possible cells will be indicated. [John’s Story] - -## Project Starter Code - -Your team may choose to use this repo as starter code for your project. You could -also use the lab 5 code — or start from an empty repo if your team prefers. - -If you choose to use one of the repositories we have provided, you can either make -a fork of it or copy the subset of code you want into a completely new repository. From 219c164b59f9857c5a3f3efdb7e4e3a58aaea275 Mon Sep 17 00:00:00 2001 From: DMA <105755300+DDMMMAA@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:23:29 -0500 Subject: [PATCH 008/125] Delete project blueprint draft i guess.docx --- project blueprint draft i guess.docx | Bin 19657 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 project blueprint draft i guess.docx diff --git a/project blueprint draft i guess.docx b/project blueprint draft i guess.docx deleted file mode 100644 index 6f135ddacaee90204b5bf2682d9420488f2bead4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19657 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 Gf_MO}$1nQ; From 491462ee33b9b25782f33b0d841eabc2692440e6 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Mon, 4 Nov 2024 16:28:40 -0500 Subject: [PATCH 009/125] Yann's Github username added. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8aa071e6b..b1a2e999d 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Michelle Bakman - 207moment John Ding - J0hnDing -Yann Chi - ... +Yann Chi - YannChi22 ## Project Domain From 9491a5a6d9c6b2a6972620d65fb7af4515c25c16 Mon Sep 17 00:00:00 2001 From: DMA <105755300+DDMMMAA@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:35:44 -0500 Subject: [PATCH 010/125] Add group user story to README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 8aa071e6b..b384dcfbb 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ If a user is logged in, they should be able to access any past puzzle scores or ## User Stories +Group User Story. Tom generate a chess puzzle, solve it step by step, and eventually win. + 1. John wants to play a chess puzzle. He opens the chess puzzle player and clicks generate puzzle of the day. The chess puzzle of the day loads on screen. [Michelle’s Story] 2. Tom and Tim argued about who is a better chess player, so they decided to compare their Rank point of Ranking system. [Jiaqi Ma’s Story] 3. As Mary hears about this chess puzzle, she wants to create an account and log in to start a puzzle. [Chihana’s Story] From dc069ffcbe4f0ec7ae3c62b9e688723a2323697b Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Mon, 11 Nov 2024 15:49:09 -0500 Subject: [PATCH 011/125] Yann's Github username added. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b1a2e999d..74b88c140 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Yann Chi - YannChi22 The domain will be able to generate random chess puzzles with options for daily, random puzzles, or specifically themed puzzles. A user will be able to view their puzzle statistics or review past puzzles within the current session of the program. Users should have the option to log in or create an account [built into the lichess api]. -If a user is logged in, they should be able to access any past puzzle scores or game histories they’ve played on that account +If a user is logged in, they should be able to access any past puzzle scores or game histories they’ve played on that account. ## User Stories From 079873ae272b6a2f492bf4dd0ed48cb52a5c2de8 Mon Sep 17 00:00:00 2001 From: DMA <1670639177@qq.com> Date: Mon, 11 Nov 2024 16:07:06 -0500 Subject: [PATCH 012/125] add 'rankPointHistory' instance variable, 'getter', and 'addRankPointHistory' --- src/main/java/entity/User.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/entity/User.java b/src/main/java/entity/User.java index e0c57e9a6..fb44b741a 100644 --- a/src/main/java/entity/User.java +++ b/src/main/java/entity/User.java @@ -1,5 +1,7 @@ package entity; +import java.util.ArrayList; + /** * The representation of a password-protected user for our program. */ @@ -7,10 +9,13 @@ public class User { private final String name; private final String password; + private ArrayList rankPointHistory; public User(String name, String password) { this.name = name; this.password = password; + this.rankPointHistory = new ArrayList<>(); + this.rankPointHistory.add(0); } public String getName() { @@ -21,4 +26,16 @@ public String getPassword() { return password; } + public ArrayList getRankPointHistory() { + return rankPointHistory; + } + + /** + * This method add latest rankPoint to the end of rankPointHistory. + * @param rankPoint is the new rankPoint after one puzzle finished + */ + public void addRankPointHistory(int rankPoint) { + this.rankPointHistory.add(rankPoint); + } + } From f9d5f027e154d3ed7d040efa667e38f35a326efc Mon Sep 17 00:00:00 2001 From: DMA <1670639177@qq.com> Date: Mon, 11 Nov 2024 16:21:40 -0500 Subject: [PATCH 013/125] add new method 'getCurrentRankPoint' that return the last element of 'rankPointHistory', correspond to current rankPoint --- src/main/java/entity/User.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/entity/User.java b/src/main/java/entity/User.java index fb44b741a..398ccef03 100644 --- a/src/main/java/entity/User.java +++ b/src/main/java/entity/User.java @@ -30,6 +30,14 @@ public ArrayList getRankPointHistory() { return rankPointHistory; } + /** + * Return current rankPoint, last element of 'rankPointHistory'. + * @return current rankPoint, last element of 'rankPointHistory' + */ + public int getCurrentRankPoint() { + return rankPointHistory.get(rankPointHistory.size() - 1); + } + /** * This method add latest rankPoint to the end of rankPointHistory. * @param rankPoint is the new rankPoint after one puzzle finished From 4ca7884d32451282e70100fb7233bd914a560142 Mon Sep 17 00:00:00 2001 From: J0hnDing Date: Mon, 11 Nov 2024 16:34:50 -0500 Subject: [PATCH 014/125] Entities with minimal functions --- src/main/java/entity/Board.java | 17 ++++++++++++++ src/main/java/entity/ChessPiece.java | 26 ++++++++++++++++++++++ src/main/java/entity/Game.java | 33 ++++++++++++++++++++++++++++ src/main/java/entity/Rook.java | 31 ++++++++++++++++++++++++++ src/main/java/usecase/Move.java | 15 +++++++++++++ 5 files changed, 122 insertions(+) create mode 100644 src/main/java/entity/Board.java create mode 100644 src/main/java/entity/ChessPiece.java create mode 100644 src/main/java/entity/Game.java create mode 100644 src/main/java/entity/Rook.java create mode 100644 src/main/java/usecase/Move.java diff --git a/src/main/java/entity/Board.java b/src/main/java/entity/Board.java new file mode 100644 index 000000000..0b8d2cf05 --- /dev/null +++ b/src/main/java/entity/Board.java @@ -0,0 +1,17 @@ +package entity; + +public class Board { + private ChessPiece[][] grid; + + public Board() { + grid = new ChessPiece[8][8]; + } + + public boolean isEmpty(int x, int y) { + return grid[x][y] == null; + } + + public ChessPiece getPiece(int x, int y) { + return grid[x][y]; + } +} diff --git a/src/main/java/entity/ChessPiece.java b/src/main/java/entity/ChessPiece.java new file mode 100644 index 000000000..30db84b8f --- /dev/null +++ b/src/main/java/entity/ChessPiece.java @@ -0,0 +1,26 @@ +package entity; + +import java.util.List; +import java.util.ArrayList; + +public abstract class ChessPiece { + private String color; + private int x; + private int y; + + public ChessPiece(String color, int x, int y) { + this.color = color; + this.x = x; + this.y = y; + } + + public abstract List getValidMoves(Board board); + + public String getColor() { + return color; + } + + public int[] getPosition() { + return new int[] {this.x, this.y}; + } +} diff --git a/src/main/java/entity/Game.java b/src/main/java/entity/Game.java new file mode 100644 index 000000000..b3fd6339d --- /dev/null +++ b/src/main/java/entity/Game.java @@ -0,0 +1,33 @@ +package entity; + +public class Game { + private Board board; + private String currentPlayer; + private boolean gameOver; + private boolean whiteTurn; + + public Game(Board board, boolean whiteTurn) { + this.board = board; + this.currentPlayer = null; + this.gameOver = false; + this.whiteTurn = whiteTurn; + } + + public void switchTurn() { + if (whiteTurn) { + whiteTurn = false; + } + else { + whiteTurn = true; + } + } + + public String getCurrentPlayer() { + if (currentPlayer == null) { + return "No Player Selected"; + } + else { + return currentPlayer; + } + } +} diff --git a/src/main/java/entity/Rook.java b/src/main/java/entity/Rook.java new file mode 100644 index 000000000..d874b231c --- /dev/null +++ b/src/main/java/entity/Rook.java @@ -0,0 +1,31 @@ +package entity; + +import java.util.ArrayList; +import java.util.List; + +public class Rook extends ChessPiece { + public Rook(String color, int x, int y) { + super(color, x, y); + } + + public List getValidMoves(Board board) { + final List validMoves = new ArrayList<>(); + final int x = this.getPosition()[0]; + final int y = this.getPosition()[1]; + + for (int i = y - 1; i >= 02; i--) { + validMoves.add(new int[] {x, i}); // Move upwards in the column + } + for (int i = y + 1; i < 8; i++) { + validMoves.add(new int[] {x, i}); // Move downwards in the column + } + + for (int i = x - 1; i >= 0; i--) { + validMoves.add(new int[] {i, y}); // Move left in the row + } + for (int i = x + 1; i < 8; i++) { + validMoves.add(new int[] {i, y}); // Move right in the row + } + return validMoves; + } +} \ No newline at end of file diff --git a/src/main/java/usecase/Move.java b/src/main/java/usecase/Move.java new file mode 100644 index 000000000..35eefb243 --- /dev/null +++ b/src/main/java/usecase/Move.java @@ -0,0 +1,15 @@ +package usecase; + +public class Move { + private entity.Board board; + private entity.Game game; + + public Move(entity.Board board, entity.Game game) { + this.board = board; + this.game = game; + } + + public boolean move() { + //updates the board if a valid move + } +} From 6289d3ef28c6b9d106501d5f2faddbea15919b6a Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Thu, 14 Nov 2024 20:31:36 -0500 Subject: [PATCH 015/125] 'ShowProfile' use case in Package 'src/main/java/use_case/showProfile/' complete --- .../showProfile/ShowProfileInputBoundary.java | 13 +++++++++ .../showProfile/ShowProfileInputData.java | 16 +++++++++++ .../showProfile/ShowProfileInteractor.java | 27 +++++++++++++++++++ .../ShowProfileOutputBoundary.java | 19 +++++++++++++ .../showProfile/ShowProfileOutputData.java | 22 +++++++++++++++ .../ShowProfileUserDataAccessInterface.java | 23 ++++++++++++++++ 6 files changed, 120 insertions(+) create mode 100644 src/main/java/use_case/showProfile/ShowProfileInputBoundary.java create mode 100644 src/main/java/use_case/showProfile/ShowProfileInputData.java create mode 100644 src/main/java/use_case/showProfile/ShowProfileInteractor.java create mode 100644 src/main/java/use_case/showProfile/ShowProfileOutputBoundary.java create mode 100644 src/main/java/use_case/showProfile/ShowProfileOutputData.java create mode 100644 src/main/java/use_case/showProfile/ShowProfileUserDataAccessInterface.java diff --git a/src/main/java/use_case/showProfile/ShowProfileInputBoundary.java b/src/main/java/use_case/showProfile/ShowProfileInputBoundary.java new file mode 100644 index 000000000..7ef135254 --- /dev/null +++ b/src/main/java/use_case/showProfile/ShowProfileInputBoundary.java @@ -0,0 +1,13 @@ +package use_case.showProfile; + +/** + * Input Boundary for actions related to logging in. + */ +public interface ShowProfileInputBoundary { + + /** + * Executes the login use case. + * @param showProfileInputData the input data + */ + void execute(ShowProfileInputData showProfileInputData); +} diff --git a/src/main/java/use_case/showProfile/ShowProfileInputData.java b/src/main/java/use_case/showProfile/ShowProfileInputData.java new file mode 100644 index 000000000..83daf5d42 --- /dev/null +++ b/src/main/java/use_case/showProfile/ShowProfileInputData.java @@ -0,0 +1,16 @@ +package use_case.showProfile; + +/** + * The Input Data for the ShowProfile use case. + */ +public class ShowProfileInputData { + private final String username; + + public ShowProfileInputData(String username) { + this.username = username; + } + + public String getUsername() { + return username; + } +} diff --git a/src/main/java/use_case/showProfile/ShowProfileInteractor.java b/src/main/java/use_case/showProfile/ShowProfileInteractor.java new file mode 100644 index 000000000..d1b35d38f --- /dev/null +++ b/src/main/java/use_case/showProfile/ShowProfileInteractor.java @@ -0,0 +1,27 @@ +package use_case.showProfile; + +import entity.User; + +/** + * The ShowProfile Interactor. + */ +public class ShowProfileInteractor implements ShowProfileInputBoundary { + private final ShowProfileUserDataAccessInterface userDataAccessObject; + private final ShowProfileOutputBoundary showProfilePresenter; + + public ShowProfileInteractor(ShowProfileUserDataAccessInterface userDataAccessObject, + ShowProfileOutputBoundary showProfilePresenter) { + this.userDataAccessObject = userDataAccessObject; + this.showProfilePresenter = showProfilePresenter; + } + + @Override + public void execute(ShowProfileInputData showProfileInputData) { + // The following code only handle success use case call + // Because I currently don't know what can cause this use case to fail + final User user = userDataAccessObject.get(showProfileInputData.getUsername()); + final ShowProfileOutputData showProfileOutputData = new ShowProfileOutputData(user.getRankPointHistory(), + true); + showProfilePresenter.prepareSuccessView(showProfileOutputData); + } +} diff --git a/src/main/java/use_case/showProfile/ShowProfileOutputBoundary.java b/src/main/java/use_case/showProfile/ShowProfileOutputBoundary.java new file mode 100644 index 000000000..2164cb5ad --- /dev/null +++ b/src/main/java/use_case/showProfile/ShowProfileOutputBoundary.java @@ -0,0 +1,19 @@ +package use_case.showProfile; + +/** + * The output boundary for the ShowProfile Use Case. + */ +public interface ShowProfileOutputBoundary { + + /** + * Prepares the success view for the ShowProfile Use Case. + * @param outputData the output data + */ + void prepareSuccessView(ShowProfileOutputData outputData); + + /** + * Prepares the failure view for the ShowProfile Use Case. + * @param errorMessage the explanation of the failure + */ + void prepareFailView(String errorMessage); +} diff --git a/src/main/java/use_case/showProfile/ShowProfileOutputData.java b/src/main/java/use_case/showProfile/ShowProfileOutputData.java new file mode 100644 index 000000000..16d639fa5 --- /dev/null +++ b/src/main/java/use_case/showProfile/ShowProfileOutputData.java @@ -0,0 +1,22 @@ +package use_case.showProfile; + +import java.util.ArrayList; + +/** + * Output Data for the ShowProfile Use case. + */ +public class ShowProfileOutputData { + + private final ArrayList rankPointHistory; + private final boolean useCaseSucceeded; + + public ShowProfileOutputData(ArrayList rankPointHistory, boolean useCaseSucceeded) { + this.rankPointHistory = rankPointHistory; + this.useCaseSucceeded = useCaseSucceeded; + } + + public ArrayList getRankPointHistory() { + return rankPointHistory; + } + +} diff --git a/src/main/java/use_case/showProfile/ShowProfileUserDataAccessInterface.java b/src/main/java/use_case/showProfile/ShowProfileUserDataAccessInterface.java new file mode 100644 index 000000000..7b3d80a27 --- /dev/null +++ b/src/main/java/use_case/showProfile/ShowProfileUserDataAccessInterface.java @@ -0,0 +1,23 @@ +package use_case.showProfile; + +import entity.User; + +/** + * DAO for the ShowProfile Use Case. + */ +public interface ShowProfileUserDataAccessInterface { + + /** + * Saves the user. + * @param user the user to save + */ + void save(User user); + + /** + * Returns the user with the given username. + * @param username the username to look up + * @return the user with the given username + */ + User get(String username); + +} From 2d776a8bb4979e9b25e360268873dfb9b5a954a3 Mon Sep 17 00:00:00 2001 From: J0hnDing Date: Mon, 18 Nov 2024 15:53:36 -0500 Subject: [PATCH 016/125] Fixed move class and chesspiece class as noted --- src/main/java/entity/ChessPiece.java | 11 +++++------ src/main/java/entity/Rook.java | 4 ++-- src/main/java/{usecase => use_case/move}/Move.java | 6 ++---- 3 files changed, 9 insertions(+), 12 deletions(-) rename src/main/java/{usecase => use_case/move}/Move.java (55%) diff --git a/src/main/java/entity/ChessPiece.java b/src/main/java/entity/ChessPiece.java index 30db84b8f..7cab94b78 100644 --- a/src/main/java/entity/ChessPiece.java +++ b/src/main/java/entity/ChessPiece.java @@ -5,13 +5,12 @@ public abstract class ChessPiece { private String color; - private int x; - private int y; + private List position; public ChessPiece(String color, int x, int y) { this.color = color; - this.x = x; - this.y = y; + position.add(x); + position.add(y); } public abstract List getValidMoves(Board board); @@ -20,7 +19,7 @@ public String getColor() { return color; } - public int[] getPosition() { - return new int[] {this.x, this.y}; + public List getPosition() { + return this.position; } } diff --git a/src/main/java/entity/Rook.java b/src/main/java/entity/Rook.java index d874b231c..01444ab92 100644 --- a/src/main/java/entity/Rook.java +++ b/src/main/java/entity/Rook.java @@ -10,8 +10,8 @@ public Rook(String color, int x, int y) { public List getValidMoves(Board board) { final List validMoves = new ArrayList<>(); - final int x = this.getPosition()[0]; - final int y = this.getPosition()[1]; + final int x = this.getPosition().get(0); + final int y = this.getPosition().get(1); for (int i = y - 1; i >= 02; i--) { validMoves.add(new int[] {x, i}); // Move upwards in the column diff --git a/src/main/java/usecase/Move.java b/src/main/java/use_case/move/Move.java similarity index 55% rename from src/main/java/usecase/Move.java rename to src/main/java/use_case/move/Move.java index 35eefb243..d53967f8b 100644 --- a/src/main/java/usecase/Move.java +++ b/src/main/java/use_case/move/Move.java @@ -1,11 +1,9 @@ -package usecase; +package use_case.move; public class Move { - private entity.Board board; private entity.Game game; - public Move(entity.Board board, entity.Game game) { - this.board = board; + public Move(entity.Game game) { this.game = game; } From eb78a4f9fb5c3e068faa6c00824333a6fbc17116 Mon Sep 17 00:00:00 2001 From: DMA <1670639177@qq.com> Date: Mon, 18 Nov 2024 16:22:58 -0500 Subject: [PATCH 017/125] partial implimentation of 'showprofile' interface_adapter and 'profile' interface_adapter --- src/main/java/interface_adapter/ViewManagerModel.java | 4 ++++ src/main/java/interface_adapter/profile/ProfileState.java | 4 ++++ src/main/java/interface_adapter/profile/ProfileViewModel.java | 4 ++++ .../interface_adapter/showProfile/ShowProfileController.java | 4 ++++ .../interface_adapter/showProfile/ShowProfilePresenter.java | 4 ++++ .../java/interface_adapter/showProfile/ShowProfileState.java | 4 ++++ .../interface_adapter/showProfile/ShowProfileViewModel.java | 4 ++++ 7 files changed, 28 insertions(+) create mode 100644 src/main/java/interface_adapter/ViewManagerModel.java create mode 100644 src/main/java/interface_adapter/profile/ProfileState.java create mode 100644 src/main/java/interface_adapter/profile/ProfileViewModel.java create mode 100644 src/main/java/interface_adapter/showProfile/ShowProfileController.java create mode 100644 src/main/java/interface_adapter/showProfile/ShowProfilePresenter.java create mode 100644 src/main/java/interface_adapter/showProfile/ShowProfileState.java create mode 100644 src/main/java/interface_adapter/showProfile/ShowProfileViewModel.java diff --git a/src/main/java/interface_adapter/ViewManagerModel.java b/src/main/java/interface_adapter/ViewManagerModel.java new file mode 100644 index 000000000..808935cbd --- /dev/null +++ b/src/main/java/interface_adapter/ViewManagerModel.java @@ -0,0 +1,4 @@ +package interface_adapter; + +public class ViewManagerModel { +} diff --git a/src/main/java/interface_adapter/profile/ProfileState.java b/src/main/java/interface_adapter/profile/ProfileState.java new file mode 100644 index 000000000..92c1602c0 --- /dev/null +++ b/src/main/java/interface_adapter/profile/ProfileState.java @@ -0,0 +1,4 @@ +package interface_adapter.profile; + +public class ProfileState { +} diff --git a/src/main/java/interface_adapter/profile/ProfileViewModel.java b/src/main/java/interface_adapter/profile/ProfileViewModel.java new file mode 100644 index 000000000..6888e9619 --- /dev/null +++ b/src/main/java/interface_adapter/profile/ProfileViewModel.java @@ -0,0 +1,4 @@ +package interface_adapter.profile; + +public class ProfileViewModel { +} diff --git a/src/main/java/interface_adapter/showProfile/ShowProfileController.java b/src/main/java/interface_adapter/showProfile/ShowProfileController.java new file mode 100644 index 000000000..69e15439a --- /dev/null +++ b/src/main/java/interface_adapter/showProfile/ShowProfileController.java @@ -0,0 +1,4 @@ +package interface_adapter.showProfile; + +public class ShowProfileController { +} diff --git a/src/main/java/interface_adapter/showProfile/ShowProfilePresenter.java b/src/main/java/interface_adapter/showProfile/ShowProfilePresenter.java new file mode 100644 index 000000000..90e50f57c --- /dev/null +++ b/src/main/java/interface_adapter/showProfile/ShowProfilePresenter.java @@ -0,0 +1,4 @@ +package interface_adapter.showProfile; + +public class ShowProfilePresenter { +} diff --git a/src/main/java/interface_adapter/showProfile/ShowProfileState.java b/src/main/java/interface_adapter/showProfile/ShowProfileState.java new file mode 100644 index 000000000..20d6acccf --- /dev/null +++ b/src/main/java/interface_adapter/showProfile/ShowProfileState.java @@ -0,0 +1,4 @@ +package interface_adapter.showProfile; + +public class ShowProfileState { +} diff --git a/src/main/java/interface_adapter/showProfile/ShowProfileViewModel.java b/src/main/java/interface_adapter/showProfile/ShowProfileViewModel.java new file mode 100644 index 000000000..af59a677a --- /dev/null +++ b/src/main/java/interface_adapter/showProfile/ShowProfileViewModel.java @@ -0,0 +1,4 @@ +package interface_adapter.showProfile; + +public class ShowProfileViewModel { +} From dbcf2116a3c2cd973a75ac5e9d24e5e4d2ff254b Mon Sep 17 00:00:00 2001 From: 207moment Date: Thu, 21 Nov 2024 11:04:07 -0500 Subject: [PATCH 018/125] Small checkstyle edits to Board and Move. Barebones Daily Puzzle use case files to experiment with API calling. --- src/main/java/entity/Board.java | 30 +++++++++-- .../daily_puzzle/DailyPuzzleInteractor.java | 54 +++++++++++++++++++ .../DailyPuzzleOutputBoundary.java | 19 +++++++ .../daily_puzzle/DailyPuzzleOutputData.java | 23 ++++++++ src/main/java/use_case/move/Move.java | 10 +++- 5 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 src/main/java/use_case/daily_puzzle/DailyPuzzleInteractor.java create mode 100644 src/main/java/use_case/daily_puzzle/DailyPuzzleOutputBoundary.java create mode 100644 src/main/java/use_case/daily_puzzle/DailyPuzzleOutputData.java diff --git a/src/main/java/entity/Board.java b/src/main/java/entity/Board.java index 0b8d2cf05..6264e1e98 100644 --- a/src/main/java/entity/Board.java +++ b/src/main/java/entity/Board.java @@ -1,5 +1,10 @@ package entity; +import org.json.JSONObject; + +/** + * The chess board entity. + */ public class Board { private ChessPiece[][] grid; @@ -7,11 +12,28 @@ public Board() { grid = new ChessPiece[8][8]; } - public boolean isEmpty(int x, int y) { - return grid[x][y] == null; + public Board(JSONObject boardFile) { + // will call some other method to read the file, placeholder for now. + } + + /** + * Returns if a tile is empty. + * @param col Column of tile + * @param row Row of tile + * @return bool + */ + public boolean isEmpty(int col, int row) { + return grid[col][row] == null; } - public ChessPiece getPiece(int x, int y) { - return grid[x][y]; + /** + * Returns the chess piece at a given tile. + * @param col Column of tile + * @param row Row of tile + * @return Chesspiece + */ + public ChessPiece getPiece(int col, int row) { + return grid[col][row]; } + } diff --git a/src/main/java/use_case/daily_puzzle/DailyPuzzleInteractor.java b/src/main/java/use_case/daily_puzzle/DailyPuzzleInteractor.java new file mode 100644 index 000000000..8e9508569 --- /dev/null +++ b/src/main/java/use_case/daily_puzzle/DailyPuzzleInteractor.java @@ -0,0 +1,54 @@ +package use_case.daily_puzzle; + +import java.io.IOException; + +import org.json.JSONException; +import org.json.JSONObject; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +/** + * The daily puzzle interactor. + */ +public class DailyPuzzleInteractor { + private static final String LICHESS_URL = "https://lichess.org/api/puzzle/daily"; + private static final String TOKEN = "token"; + private final DailyPuzzleOutputBoundary puzzlePresenter; + + public DailyPuzzleInteractor(DailyPuzzleOutputBoundary dailyPuzzleOutputBoundary) { + this.puzzlePresenter = dailyPuzzleOutputBoundary; + } + + public static String getToken() { + return System.getenv(TOKEN); + } + + /** + * Executes the use case. + * @throws RuntimeException if API request fails. + */ + public void execute() { + final OkHttpClient client = new OkHttpClient().newBuilder().build(); + final Request request = new Request.Builder().url(LICHESS_URL).build(); + final JSONObject output; + + try { + final Response response = client.newCall(request).execute(); + final JSONObject responseBody = new JSONObject(response.body().string()); + + System.out.println(responseBody); + output = responseBody; + // placeholder, actual will call the view to make a board with the JSON. + } + catch (IOException | JSONException event) { + throw new RuntimeException(event); + } + + final DailyPuzzleOutputData outputData = new DailyPuzzleOutputData(output, false); + // fail checks/generating erorr message will come later, just want to see it works first + puzzlePresenter.prepareSuccessView(outputData); + + } +} diff --git a/src/main/java/use_case/daily_puzzle/DailyPuzzleOutputBoundary.java b/src/main/java/use_case/daily_puzzle/DailyPuzzleOutputBoundary.java new file mode 100644 index 000000000..671590506 --- /dev/null +++ b/src/main/java/use_case/daily_puzzle/DailyPuzzleOutputBoundary.java @@ -0,0 +1,19 @@ +package use_case.daily_puzzle; + +/** + * The output boundary for the Daily Puzzle Use case. + */ +public interface DailyPuzzleOutputBoundary { + + /** + * Prepares the success view for the daily puzzle use case. + * @param outputData The puzzle's JSON file + */ + void prepareSuccessView(DailyPuzzleOutputData outputData); + + /** + * Prepares the fail view for the daily puzzle use case. + * @param errorMessage Explanation of the failure + */ + void prepareFailView(String errorMessage); +} diff --git a/src/main/java/use_case/daily_puzzle/DailyPuzzleOutputData.java b/src/main/java/use_case/daily_puzzle/DailyPuzzleOutputData.java new file mode 100644 index 000000000..fa7cda81f --- /dev/null +++ b/src/main/java/use_case/daily_puzzle/DailyPuzzleOutputData.java @@ -0,0 +1,23 @@ +package use_case.daily_puzzle; + +import org.json.JSONObject; + +/** + * Output data for the daily puzzle use case. + */ +public class DailyPuzzleOutputData { + + private final JSONObject puzzle; + + private final boolean useCaseFailed; + + public DailyPuzzleOutputData(JSONObject puzzle, boolean useCaseFailed) { + this.puzzle = puzzle; + this.useCaseFailed = useCaseFailed; + } + + public JSONObject getPuzzle() { + return puzzle; + } + // could change later to be board and this or the interactor will call for board generation. +} diff --git a/src/main/java/use_case/move/Move.java b/src/main/java/use_case/move/Move.java index d53967f8b..1c0456da1 100644 --- a/src/main/java/use_case/move/Move.java +++ b/src/main/java/use_case/move/Move.java @@ -1,5 +1,8 @@ package use_case.move; +/** + * Use case for moving a piece. + */ public class Move { private entity.Game game; @@ -7,7 +10,12 @@ public Move(entity.Game game) { this.game = game; } + /** + * Returns whether move was successful. + * @return bool + */ public boolean move() { - //updates the board if a valid move + return true; + // updates the board if a valid move, currently placeholder } } From b5917ecec7ebe5f25ade62b6074816cc120aa2d2 Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Thu, 21 Nov 2024 18:19:24 -0500 Subject: [PATCH 019/125] all new file added in this commit comtain only minimal template (no logic), except 'MoveViewModel.java' & 'ChessBoardView.java' & 'ViewManager.java' which implemented to show a chessboard with pieces view. PS. default chessboard view can be seen by running 'ChessBoardViewTest.java' --- pom.xml | 5 ++ src/main/java/app/ChessAppBuilder.java | 4 ++ src/main/java/app/MainChessApp.java | 11 +++ .../data_access/ChessDataAccessObject.java | 4 ++ .../interface_adapter/ViewManagerModel.java | 12 +++- .../move/MoveController.java | 7 ++ .../interface_adapter/move/MovePresenter.java | 4 ++ .../interface_adapter/move/MoveState.java | 4 ++ .../interface_adapter/move/MoveViewModel.java | 31 ++++++++ src/main/java/view/ChessBoardView.java | 70 +++++++++++++++++++ src/main/java/view/ViewManager.java | 34 +++++++++ src/test/java/view/ChessBoardViewTest.java | 26 +++++++ 12 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 src/main/java/app/ChessAppBuilder.java create mode 100644 src/main/java/app/MainChessApp.java create mode 100644 src/main/java/data_access/ChessDataAccessObject.java create mode 100644 src/main/java/interface_adapter/move/MoveController.java create mode 100644 src/main/java/interface_adapter/move/MovePresenter.java create mode 100644 src/main/java/interface_adapter/move/MoveState.java create mode 100644 src/main/java/interface_adapter/move/MoveViewModel.java create mode 100644 src/main/java/view/ChessBoardView.java create mode 100644 src/main/java/view/ViewManager.java create mode 100644 src/test/java/view/ChessBoardViewTest.java diff --git a/pom.xml b/pom.xml index 527f61e36..428273a2a 100644 --- a/pom.xml +++ b/pom.xml @@ -27,6 +27,11 @@ 4.13.1 test + + io.github.tors42 + chariot + 0.1.10 + diff --git a/src/main/java/app/ChessAppBuilder.java b/src/main/java/app/ChessAppBuilder.java new file mode 100644 index 000000000..75241c2e6 --- /dev/null +++ b/src/main/java/app/ChessAppBuilder.java @@ -0,0 +1,4 @@ +package app; + +public class ChessAppBuilder { +} diff --git a/src/main/java/app/MainChessApp.java b/src/main/java/app/MainChessApp.java new file mode 100644 index 000000000..55c210584 --- /dev/null +++ b/src/main/java/app/MainChessApp.java @@ -0,0 +1,11 @@ +package app; + +import data_access.ChessDataAccessObject; +import use_case.note.NoteDataAccessInterface; + +public class MainChessApp { + + public static void main(String[] args) { + + } +} diff --git a/src/main/java/data_access/ChessDataAccessObject.java b/src/main/java/data_access/ChessDataAccessObject.java new file mode 100644 index 000000000..6f1a2a880 --- /dev/null +++ b/src/main/java/data_access/ChessDataAccessObject.java @@ -0,0 +1,4 @@ +package data_access; + +public class ChessDataAccessObject { +} diff --git a/src/main/java/interface_adapter/ViewManagerModel.java b/src/main/java/interface_adapter/ViewManagerModel.java index 808935cbd..99dc0ffe5 100644 --- a/src/main/java/interface_adapter/ViewManagerModel.java +++ b/src/main/java/interface_adapter/ViewManagerModel.java @@ -1,4 +1,14 @@ package interface_adapter; -public class ViewManagerModel { +/** + * Model for the View Manager. Its state is the name of the View which + * is currently active. An initial state of "" is used. + */ +public class ViewManagerModel extends ViewModel { + + public ViewManagerModel() { + super("view manager"); + this.setState(""); + } + } diff --git a/src/main/java/interface_adapter/move/MoveController.java b/src/main/java/interface_adapter/move/MoveController.java new file mode 100644 index 000000000..8ffbbc434 --- /dev/null +++ b/src/main/java/interface_adapter/move/MoveController.java @@ -0,0 +1,7 @@ +package interface_adapter.move; + +/** + * The controller for the Move Use Case. + */ +public class MoveController { +} diff --git a/src/main/java/interface_adapter/move/MovePresenter.java b/src/main/java/interface_adapter/move/MovePresenter.java new file mode 100644 index 000000000..2161e5c15 --- /dev/null +++ b/src/main/java/interface_adapter/move/MovePresenter.java @@ -0,0 +1,4 @@ +package interface_adapter.move; + +public class MovePresenter { +} diff --git a/src/main/java/interface_adapter/move/MoveState.java b/src/main/java/interface_adapter/move/MoveState.java new file mode 100644 index 000000000..9abd2f4c7 --- /dev/null +++ b/src/main/java/interface_adapter/move/MoveState.java @@ -0,0 +1,4 @@ +package interface_adapter.move; + +public class MoveState { +} diff --git a/src/main/java/interface_adapter/move/MoveViewModel.java b/src/main/java/interface_adapter/move/MoveViewModel.java new file mode 100644 index 000000000..ef52c3711 --- /dev/null +++ b/src/main/java/interface_adapter/move/MoveViewModel.java @@ -0,0 +1,31 @@ +package interface_adapter.move; + +import interface_adapter.ViewModel; + +/** + * The ViewModel for the MoveView. + */ +public class MoveViewModel extends ViewModel { + + public static final String TITLE_LABEL = "Move View"; + + private final String[][] pieces = { + {"♖", "♘", "♗", "♕", "♔", "♗", "♘", "♖"}, // Black major pieces + {"♙", "♙", "♙", "♙", "♙", "♙", "♙", "♙"}, // Black pawns + {null, null, null, null, null, null, null, null}, // Empty row + {null, null, null, null, null, null, null, null}, // Empty row + {null, null, null, null, null, null, null, null}, // Empty row + {null, null, null, null, null, null, null, null}, // Empty row + {"♙", "♙", "♙", "♙", "♙", "♙", "♙", "♙"}, // White pawns + {"♖", "♘", "♗", "♕", "♔", "♗", "♘", "♖"} // White major pieces + }; + + public MoveViewModel() { + super("move"); + setState(new MoveState()); + } + + public String[][] getPieces() { + return pieces; + } +} diff --git a/src/main/java/view/ChessBoardView.java b/src/main/java/view/ChessBoardView.java new file mode 100644 index 000000000..89a4b0bff --- /dev/null +++ b/src/main/java/view/ChessBoardView.java @@ -0,0 +1,70 @@ +package view; + +import interface_adapter.move.MoveController; +import interface_adapter.move.MoveViewModel; + +import javax.swing.*; +import javax.swing.text.View; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/** + * The view of actual chess game. + */ +public class ChessBoardView extends JPanel implements ActionListener, PropertyChangeListener { + + private final String viewName = "Chess Board"; + private final MoveViewModel moveViewModel; + private final MoveController moveController; + + public ChessBoardView(MoveViewModel moveViewModel, MoveController moveController) { + this.moveViewModel = moveViewModel; + this.moveController = moveController; + moveViewModel.addPropertyChangeListener(this); + + final JLabel titleLabel = new JLabel(MoveViewModel.TITLE_LABEL); + + this.setLayout(new GridLayout(8, 8)); + + // Add buttons to the frame in a chessboard pattern + for (int row = 0; row < 8; row++) { + for (int col = 0; col < 8; col++) { + JButton button = new JButton(); + + // Set background color to alternate between black and white + if ((row + col) % 2 == 0) { + button.setBackground(Color.WHITE); + } + else { + button.setBackground(Color.BLACK); + } + + // Add pieces to the board + String[][] pieces = moveViewModel.getPieces(); + if (pieces[row][col] != null) { + button.setText(pieces[row][col]); + button.setFont(new Font("Serif", Font.BOLD, 36)); + } + + button.setFocusPainted(false); + button.addActionListener(this); + this.add(button); + + } + } + + } + + @Override + public void actionPerformed(ActionEvent e) { + + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + + } +} diff --git a/src/main/java/view/ViewManager.java b/src/main/java/view/ViewManager.java new file mode 100644 index 000000000..7f9f07ec6 --- /dev/null +++ b/src/main/java/view/ViewManager.java @@ -0,0 +1,34 @@ +package view; + +import java.awt.CardLayout; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.JPanel; + +import interface_adapter.ViewManagerModel; + +/** + * The View Manager for the program. It listens for property change events + * in the ViewManagerModel and updates which View should be visible. + */ +public class ViewManager implements PropertyChangeListener { + private final CardLayout cardLayout; + private final JPanel views; + private final ViewManagerModel viewManagerModel; + + public ViewManager(JPanel views, CardLayout cardLayout, ViewManagerModel viewManagerModel) { + this.views = views; + this.cardLayout = cardLayout; + this.viewManagerModel = viewManagerModel; + this.viewManagerModel.addPropertyChangeListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("state")) { + final String viewModelName = (String) evt.getNewValue(); + cardLayout.show(views, viewModelName); + } + } +} diff --git a/src/test/java/view/ChessBoardViewTest.java b/src/test/java/view/ChessBoardViewTest.java new file mode 100644 index 000000000..2b6b8ca1e --- /dev/null +++ b/src/test/java/view/ChessBoardViewTest.java @@ -0,0 +1,26 @@ +package view; + +import interface_adapter.move.MoveController; +import interface_adapter.move.MoveViewModel; + +import javax.swing.*; +import java.awt.*; + + +public class ChessBoardViewTest { + public static void main(String[] args) { + + JFrame frame = new JFrame("Test ChessBoardView"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(800, 800); + + MoveViewModel TestModel = new MoveViewModel(); + MoveController TestController = new MoveController(); + + ChessBoardView TestView = new ChessBoardView(TestModel, TestController); + + frame.add(TestView); + frame.setVisible(true); + + } +} From 92b8fcc5ab1bf89df4bd49034aabc4d12f7ea51b Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Thu, 21 Nov 2024 18:55:48 -0500 Subject: [PATCH 020/125] Yann's user story updated. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 74b88c140..080ab8ec0 100644 --- a/README.md +++ b/README.md @@ -24,5 +24,5 @@ If a user is logged in, they should be able to access any past puzzle scores or 1. John wants to play a chess puzzle. He opens the chess puzzle player and clicks generate puzzle of the day. The chess puzzle of the day loads on screen. [Michelle’s Story] 2. Tom and Tim argued about who is a better chess player, so they decided to compare their Rank point of Ranking system. [Jiaqi Ma’s Story] 3. As Mary hears about this chess puzzle, she wants to create an account and log in to start a puzzle. [Chihana’s Story] -4. Andy is learning chess, and his teacher use this program to measure Andy’s skill level, and to trend his improvement through a long period utilizing the ranking system. [Yann Chi's Story] +4. Andy is learning chess, and his teacher use this program to check Andy's learning progress, by looking at past statistics of chess puzzles. The teacher can search up Andy's user account using the email. [Yann Chi's Story] 5. Felix wants to see the possible moves he can make with one piece, so he click on that piece and the possible cells will be indicated. [John’s Story] From f5a4051ced31588fd94f0d047027e331a3e6fa9d Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Thu, 21 Nov 2024 19:14:01 -0500 Subject: [PATCH 021/125] Yann's user story updated. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 080ab8ec0..1025c8cd8 100644 --- a/README.md +++ b/README.md @@ -24,5 +24,5 @@ If a user is logged in, they should be able to access any past puzzle scores or 1. John wants to play a chess puzzle. He opens the chess puzzle player and clicks generate puzzle of the day. The chess puzzle of the day loads on screen. [Michelle’s Story] 2. Tom and Tim argued about who is a better chess player, so they decided to compare their Rank point of Ranking system. [Jiaqi Ma’s Story] 3. As Mary hears about this chess puzzle, she wants to create an account and log in to start a puzzle. [Chihana’s Story] -4. Andy is learning chess, and his teacher use this program to check Andy's learning progress, by looking at past statistics of chess puzzles. The teacher can search up Andy's user account using the email. [Yann Chi's Story] +4. Andy is learning chess, and his teacher use this program to check Andy's learning progress, by looking at past statistics of chess puzzles. The teacher can search up Andy's user account using the username. [Yann Chi's Story] 5. Felix wants to see the possible moves he can make with one piece, so he click on that piece and the possible cells will be indicated. [John’s Story] From 3b54cade4e19428eb704709b4e440728c342407c Mon Sep 17 00:00:00 2001 From: J0hnDing Date: Thu, 21 Nov 2024 19:44:14 -0500 Subject: [PATCH 022/125] Implemented Input Data, Input Boundary,Controller. Changed the type of posotion from List to ArrayList since its more explicit. --- src/main/java/entity/ChessPiece.java | 7 +++--- src/main/java/entity/Game.java | 6 ++++- src/main/java/entity/Rook.java | 5 ++-- .../move/MoveController.java | 23 +++++++++++++++++++ src/main/java/use_case/move/Move.java | 13 ----------- .../move/MoveDataAccessinterface.java | 4 ++++ .../java/use_case/move/MoveInputBoundary.java | 12 ++++++++++ .../java/use_case/move/MoveInputdata.java | 14 +++++++++++ .../java/use_case/move/MoveInteractor.java | 22 ++++++++++++++++++ .../java/use_case/move/MoveOutputPort.java | 4 ++++ .../java/use_case/move/MoveOutputdata.java | 4 ++++ 11 files changed, 93 insertions(+), 21 deletions(-) delete mode 100644 src/main/java/use_case/move/Move.java create mode 100644 src/main/java/use_case/move/MoveDataAccessinterface.java create mode 100644 src/main/java/use_case/move/MoveInputBoundary.java create mode 100644 src/main/java/use_case/move/MoveInputdata.java create mode 100644 src/main/java/use_case/move/MoveInteractor.java create mode 100644 src/main/java/use_case/move/MoveOutputPort.java create mode 100644 src/main/java/use_case/move/MoveOutputdata.java diff --git a/src/main/java/entity/ChessPiece.java b/src/main/java/entity/ChessPiece.java index 7cab94b78..5b1f9715f 100644 --- a/src/main/java/entity/ChessPiece.java +++ b/src/main/java/entity/ChessPiece.java @@ -1,11 +1,10 @@ package entity; -import java.util.List; import java.util.ArrayList; public abstract class ChessPiece { private String color; - private List position; + private ArrayList position; public ChessPiece(String color, int x, int y) { this.color = color; @@ -13,13 +12,13 @@ public ChessPiece(String color, int x, int y) { position.add(y); } - public abstract List getValidMoves(Board board); + public abstract ArrayList getValidMoves(Board board); public String getColor() { return color; } - public List getPosition() { + public ArrayList getPosition() { return this.position; } } diff --git a/src/main/java/entity/Game.java b/src/main/java/entity/Game.java index b3fd6339d..ecf9aa215 100644 --- a/src/main/java/entity/Game.java +++ b/src/main/java/entity/Game.java @@ -4,13 +4,17 @@ public class Game { private Board board; private String currentPlayer; private boolean gameOver; - private boolean whiteTurn; + private boolean whiteTurn; //if whiteturn is false, then its blacks turn + private boolean selectMode; //if select mode is false, game is in movemode. + private ChessPiece chesspiece_to_move; public Game(Board board, boolean whiteTurn) { this.board = board; this.currentPlayer = null; this.gameOver = false; this.whiteTurn = whiteTurn; + this.selectMode = true; + this.chesspiece_to_move = null; } public void switchTurn() { diff --git a/src/main/java/entity/Rook.java b/src/main/java/entity/Rook.java index 01444ab92..4ce0261cd 100644 --- a/src/main/java/entity/Rook.java +++ b/src/main/java/entity/Rook.java @@ -1,15 +1,14 @@ package entity; import java.util.ArrayList; -import java.util.List; public class Rook extends ChessPiece { public Rook(String color, int x, int y) { super(color, x, y); } - public List getValidMoves(Board board) { - final List validMoves = new ArrayList<>(); + public ArrayList getValidMoves(Board board) { + final ArrayList validMoves = new ArrayList<>(); final int x = this.getPosition().get(0); final int y = this.getPosition().get(1); diff --git a/src/main/java/interface_adapter/move/MoveController.java b/src/main/java/interface_adapter/move/MoveController.java index 8ffbbc434..0b8a038fd 100644 --- a/src/main/java/interface_adapter/move/MoveController.java +++ b/src/main/java/interface_adapter/move/MoveController.java @@ -1,7 +1,30 @@ package interface_adapter.move; +import java.util.ArrayList; + +import use_case.move.MoveInputBoundary; +import use_case.move.MoveInputdata; + /** * The controller for the Move Use Case. */ public class MoveController { + private final MoveInputBoundary moveInteractor; + + public MoveController(MoveInputBoundary moveInteractor) { + this.moveInteractor = moveInteractor; + } + + /** + * Convert the data into ArrayList and delegate the execution to move interactor. + * @param xcord the horizontal coordinate form 0 to 7 + * @param ycord the horizontal coordinate form 0 to 7 + */ + public void onClick(Integer xcord, Integer ycord) { + final ArrayList position = new ArrayList<>(); + position.add(xcord); + position.add(ycord); + final MoveInputdata moveInputdata = new MoveInputdata(position); + moveInteractor.handleClick(moveInputdata); + } } diff --git a/src/main/java/use_case/move/Move.java b/src/main/java/use_case/move/Move.java deleted file mode 100644 index d53967f8b..000000000 --- a/src/main/java/use_case/move/Move.java +++ /dev/null @@ -1,13 +0,0 @@ -package use_case.move; - -public class Move { - private entity.Game game; - - public Move(entity.Game game) { - this.game = game; - } - - public boolean move() { - //updates the board if a valid move - } -} diff --git a/src/main/java/use_case/move/MoveDataAccessinterface.java b/src/main/java/use_case/move/MoveDataAccessinterface.java new file mode 100644 index 000000000..ffe57e35a --- /dev/null +++ b/src/main/java/use_case/move/MoveDataAccessinterface.java @@ -0,0 +1,4 @@ +package use_case.move; + +public class MoveDataAccessinterface { +} diff --git a/src/main/java/use_case/move/MoveInputBoundary.java b/src/main/java/use_case/move/MoveInputBoundary.java new file mode 100644 index 000000000..1b4a4242e --- /dev/null +++ b/src/main/java/use_case/move/MoveInputBoundary.java @@ -0,0 +1,12 @@ +package use_case.move; + +/** + * Input Boundary for actions which are related to moving. + */ +public interface MoveInputBoundary { + /** + * Executes the move use case. + * @param moveInputData the input data + */ + void handleClick(MoveInputdata moveInputData); +} diff --git a/src/main/java/use_case/move/MoveInputdata.java b/src/main/java/use_case/move/MoveInputdata.java new file mode 100644 index 000000000..6e9759c23 --- /dev/null +++ b/src/main/java/use_case/move/MoveInputdata.java @@ -0,0 +1,14 @@ +package use_case.move; + +import java.util.ArrayList; + +/** + * Input data for move use case. + */ +public class MoveInputdata { + private ArrayList position; + + public MoveInputdata(ArrayList input) { + this.position = input; + } +} diff --git a/src/main/java/use_case/move/MoveInteractor.java b/src/main/java/use_case/move/MoveInteractor.java new file mode 100644 index 000000000..ce91ecb5d --- /dev/null +++ b/src/main/java/use_case/move/MoveInteractor.java @@ -0,0 +1,22 @@ +package use_case.move; + +/** + * Move interactor who handles the business logic of move. + */ +public class MoveInteractor implements MoveInputBoundary { + private entity.Game game; + + public MoveInteractor(entity.Game game) { + this.game = game; + } + + public boolean isvalidmove() { + // check if this move is valid + } + + @Override + public void handleClick(MoveInputdata position) { + // Starting point of this class + + } +} diff --git a/src/main/java/use_case/move/MoveOutputPort.java b/src/main/java/use_case/move/MoveOutputPort.java new file mode 100644 index 000000000..5359bec9a --- /dev/null +++ b/src/main/java/use_case/move/MoveOutputPort.java @@ -0,0 +1,4 @@ +package use_case.move; + +public class MoveOutputPort { +} diff --git a/src/main/java/use_case/move/MoveOutputdata.java b/src/main/java/use_case/move/MoveOutputdata.java new file mode 100644 index 000000000..91cee2112 --- /dev/null +++ b/src/main/java/use_case/move/MoveOutputdata.java @@ -0,0 +1,4 @@ +package use_case.move; + +public class MoveOutputdata { +} From 2f0393e42a63095e4b236ea33c36ba069dca9572 Mon Sep 17 00:00:00 2001 From: DMA <105755300+DDMMMAA@users.noreply.github.com> Date: Thu, 21 Nov 2024 20:06:59 -0500 Subject: [PATCH 023/125] Delete src/main/java/use_case/move/Move.java move.java deleted --- src/main/java/use_case/move/Move.java | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 src/main/java/use_case/move/Move.java diff --git a/src/main/java/use_case/move/Move.java b/src/main/java/use_case/move/Move.java deleted file mode 100644 index 1c0456da1..000000000 --- a/src/main/java/use_case/move/Move.java +++ /dev/null @@ -1,21 +0,0 @@ -package use_case.move; - -/** - * Use case for moving a piece. - */ -public class Move { - private entity.Game game; - - public Move(entity.Game game) { - this.game = game; - } - - /** - * Returns whether move was successful. - * @return bool - */ - public boolean move() { - return true; - // updates the board if a valid move, currently placeholder - } -} From 093aa924afcd8b3ec6b11b5ccabd7b8fdd0adad5 Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Thu, 21 Nov 2024 20:11:30 -0500 Subject: [PATCH 024/125] empty 'DailyPuzzleDataAccessInterface.java' added --- .../use_case/daily_puzzle/DailyPuzzleDataAccessInterface.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/main/java/use_case/daily_puzzle/DailyPuzzleDataAccessInterface.java diff --git a/src/main/java/use_case/daily_puzzle/DailyPuzzleDataAccessInterface.java b/src/main/java/use_case/daily_puzzle/DailyPuzzleDataAccessInterface.java new file mode 100644 index 000000000..5715a8ab0 --- /dev/null +++ b/src/main/java/use_case/daily_puzzle/DailyPuzzleDataAccessInterface.java @@ -0,0 +1,4 @@ +package use_case.daily_puzzle; + +public class DailyPuzzleDataAccessInterface { +} From 651332afcbd14107f410f2fb5ddd6ade95a2ac3e Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Thu, 21 Nov 2024 20:18:57 -0500 Subject: [PATCH 025/125] change MoveDataAccessInterface and MoveOutPutBoundary from class to interface by delete and recreate --- src/main/java/use_case/move/MoveDataAccessInterface.java | 4 ++++ src/main/java/use_case/move/MoveDataAccessinterface.java | 4 ---- src/main/java/use_case/move/MoveOutPutBoundary.java | 4 ++++ src/main/java/use_case/move/MoveOutputPort.java | 4 ---- 4 files changed, 8 insertions(+), 8 deletions(-) create mode 100644 src/main/java/use_case/move/MoveDataAccessInterface.java delete mode 100644 src/main/java/use_case/move/MoveDataAccessinterface.java create mode 100644 src/main/java/use_case/move/MoveOutPutBoundary.java delete mode 100644 src/main/java/use_case/move/MoveOutputPort.java diff --git a/src/main/java/use_case/move/MoveDataAccessInterface.java b/src/main/java/use_case/move/MoveDataAccessInterface.java new file mode 100644 index 000000000..b1b613e21 --- /dev/null +++ b/src/main/java/use_case/move/MoveDataAccessInterface.java @@ -0,0 +1,4 @@ +package use_case.move; + +public interface MoveDataAccessInterface { +} diff --git a/src/main/java/use_case/move/MoveDataAccessinterface.java b/src/main/java/use_case/move/MoveDataAccessinterface.java deleted file mode 100644 index ffe57e35a..000000000 --- a/src/main/java/use_case/move/MoveDataAccessinterface.java +++ /dev/null @@ -1,4 +0,0 @@ -package use_case.move; - -public class MoveDataAccessinterface { -} diff --git a/src/main/java/use_case/move/MoveOutPutBoundary.java b/src/main/java/use_case/move/MoveOutPutBoundary.java new file mode 100644 index 000000000..96c066ce1 --- /dev/null +++ b/src/main/java/use_case/move/MoveOutPutBoundary.java @@ -0,0 +1,4 @@ +package use_case.move; + +public interface MoveOutPutBoundary { +} diff --git a/src/main/java/use_case/move/MoveOutputPort.java b/src/main/java/use_case/move/MoveOutputPort.java deleted file mode 100644 index 5359bec9a..000000000 --- a/src/main/java/use_case/move/MoveOutputPort.java +++ /dev/null @@ -1,4 +0,0 @@ -package use_case.move; - -public class MoveOutputPort { -} From 411bdbf3330eabde59c86c39f480710164ae03c4 Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Fri, 22 Nov 2024 13:35:29 -0500 Subject: [PATCH 026/125] LoginInputData --- .../java/use_case/login/LoginInputData.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/main/java/use_case/login/LoginInputData.java diff --git a/src/main/java/use_case/login/LoginInputData.java b/src/main/java/use_case/login/LoginInputData.java new file mode 100644 index 000000000..c2050eb4c --- /dev/null +++ b/src/main/java/use_case/login/LoginInputData.java @@ -0,0 +1,19 @@ +package use_case.login; + +public class LoginInputData { + + private final String username; + private final String password; + + public LoginInputData(String username, String password) { + this.username = username; + this.password = password; + } + + public String getUsername() { + return username; + } + public String getPassword() { + return password; + } +} From a0e43d4dc6ee4ec78d18cded394fad6a6a6ee2ad Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Fri, 22 Nov 2024 13:47:18 -0500 Subject: [PATCH 027/125] LoginInputBoundary, LoginInteractor, LoginOutputBoundary, LoginOutputData, LoginUserDataAccessInterface --- .../use_case/login/LoginInputBoundary.java | 5 +++ .../java/use_case/login/LoginInteractor.java | 36 +++++++++++++++++++ .../use_case/login/LoginOutputBoundary.java | 7 ++++ .../java/use_case/login/LoginOutputData.java | 19 ++++++++++ .../login/LoginUserDataAccessInterface.java | 16 +++++++++ 5 files changed, 83 insertions(+) create mode 100644 src/main/java/use_case/login/LoginInputBoundary.java create mode 100644 src/main/java/use_case/login/LoginInteractor.java create mode 100644 src/main/java/use_case/login/LoginOutputBoundary.java create mode 100644 src/main/java/use_case/login/LoginOutputData.java create mode 100644 src/main/java/use_case/login/LoginUserDataAccessInterface.java diff --git a/src/main/java/use_case/login/LoginInputBoundary.java b/src/main/java/use_case/login/LoginInputBoundary.java new file mode 100644 index 000000000..15010279f --- /dev/null +++ b/src/main/java/use_case/login/LoginInputBoundary.java @@ -0,0 +1,5 @@ +package use_case.login; + +public interface LoginInputBoundary { + void execute(LoginInputData loginInputData); +} diff --git a/src/main/java/use_case/login/LoginInteractor.java b/src/main/java/use_case/login/LoginInteractor.java new file mode 100644 index 000000000..eab95611f --- /dev/null +++ b/src/main/java/use_case/login/LoginInteractor.java @@ -0,0 +1,36 @@ +package use_case.login; + +import entity.User; + +public class LoginInteractor implements LoginInputBoundary { + private final LoginUserDataAccessInterface userDataAccessObject; + private final LoginOutputBoundary loginPresenter; + + public LoginInteractor(LoginUserDataAccessInterface userDataAccessInterface, + LoginOutputBoundary loginOutputBoundary) { + this.userDataAccessObject = userDataAccessInterface; + this.loginPresenter = loginOutputBoundary; + } + + @Override + public void execute(LoginInputData loginInputData) { + final String username = loginInputData.getUsername(); + final String password = loginInputData.getPassword(); + if (!userDataAccessObject.existsByName(username)) { + loginPresenter.prepareFailView(username + ": Account does not exist."); + } + else { + final String pwd = userDataAccessObject.get(username).getPassword(); + if (!password.equals(pwd)) { + loginPresenter.prepareFailView("Incorrect password for \"" + username + "\"."); + } + else { + + final User user = userDataAccessObject.get(loginInputData.getUsername()); + userDataAccessObject.setCurrentUser(user.getName()); + final LoginOutputData loginOutputData = new LoginOutputData(user.getName(), false); + loginPresenter.prepareSuccessView(loginOutputData); + } + } + } +} diff --git a/src/main/java/use_case/login/LoginOutputBoundary.java b/src/main/java/use_case/login/LoginOutputBoundary.java new file mode 100644 index 000000000..eff2b9faa --- /dev/null +++ b/src/main/java/use_case/login/LoginOutputBoundary.java @@ -0,0 +1,7 @@ +package use_case.login; + +public interface LoginOutputBoundary { + void prepareSuccessView(LoginOutputData loginoutputdata); + + void prepareFailView(String errorMessage); +} diff --git a/src/main/java/use_case/login/LoginOutputData.java b/src/main/java/use_case/login/LoginOutputData.java new file mode 100644 index 000000000..9814ea504 --- /dev/null +++ b/src/main/java/use_case/login/LoginOutputData.java @@ -0,0 +1,19 @@ +package use_case.login; + +public class LoginOutputData { + private final String username; + private final boolean useCaseFailed; + + public LoginOutputData(String username, boolean useCaseFailed) { + this.username = username; + this.useCaseFailed = useCaseFailed; + } + + public String getUsername() { + return username; + } + + public boolean isUseCaseFailed() { + return useCaseFailed; + } +} \ No newline at end of file diff --git a/src/main/java/use_case/login/LoginUserDataAccessInterface.java b/src/main/java/use_case/login/LoginUserDataAccessInterface.java new file mode 100644 index 000000000..a9c256ac9 --- /dev/null +++ b/src/main/java/use_case/login/LoginUserDataAccessInterface.java @@ -0,0 +1,16 @@ +package use_case.login; + +import entity.User; + +public class LoginUserDataAccessInterface { + + boolean existsByName(String username); + + void save(User user); + + User get(String username); + + void setCurrentUser(String name); + + String getCurrentUser(); +} From 8187e6e1748ce13a058102ed80b87087bff50984 Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Fri, 22 Nov 2024 15:05:29 -0500 Subject: [PATCH 028/125] SignupInputBoundary, SignupInputData, SignupInteractor, SignupOutputBoundary, SignupOutputData --- .../data_access/ChessDataAccessObject.java | 1 + src/main/java/entity/UserFactory.java | 16 +++++++ .../login/LoginController.java | 28 +++++++++++++ .../use_case/login/LoginInputBoundary.java | 7 ++++ .../java/use_case/login/LoginInputData.java | 4 ++ .../java/use_case/login/LoginInteractor.java | 3 ++ .../use_case/login/LoginOutputBoundary.java | 14 ++++++- .../java/use_case/login/LoginOutputData.java | 5 ++- .../login/LoginUserDataAccessInterface.java | 19 ++++++++- .../use_case/signup/SignupInputBoundary.java | 18 ++++++++ .../java/use_case/signup/SignupInputData.java | 29 +++++++++++++ .../use_case/signup/SignupInteractor.java | 42 +++++++++++++++++++ .../use_case/signup/SignupOutputBoundary.java | 24 +++++++++++ .../use_case/signup/SignupOutputData.java | 24 +++++++++++ .../signup/SignupUserDataAccessInterface.java | 22 ++++++++++ 15 files changed, 252 insertions(+), 4 deletions(-) create mode 100644 src/main/java/entity/UserFactory.java create mode 100644 src/main/java/interface_adapter/login/LoginController.java create mode 100644 src/main/java/use_case/signup/SignupInputBoundary.java create mode 100644 src/main/java/use_case/signup/SignupInputData.java create mode 100644 src/main/java/use_case/signup/SignupInteractor.java create mode 100644 src/main/java/use_case/signup/SignupOutputBoundary.java create mode 100644 src/main/java/use_case/signup/SignupOutputData.java create mode 100644 src/main/java/use_case/signup/SignupUserDataAccessInterface.java diff --git a/src/main/java/data_access/ChessDataAccessObject.java b/src/main/java/data_access/ChessDataAccessObject.java index 6f1a2a880..41d9b97ed 100644 --- a/src/main/java/data_access/ChessDataAccessObject.java +++ b/src/main/java/data_access/ChessDataAccessObject.java @@ -1,4 +1,5 @@ package data_access; public class ChessDataAccessObject { + } diff --git a/src/main/java/entity/UserFactory.java b/src/main/java/entity/UserFactory.java new file mode 100644 index 000000000..d2e74c885 --- /dev/null +++ b/src/main/java/entity/UserFactory.java @@ -0,0 +1,16 @@ +package entity; + +/** + * Factory for creating users. + */ +public class UserFactory { + /** + * Creates a new User. + * @param name the name of the new user + * @param password the password of the new user + * @return the new user + */ + public User create(String name, String password) { + return new User(name, password); + } +} diff --git a/src/main/java/interface_adapter/login/LoginController.java b/src/main/java/interface_adapter/login/LoginController.java new file mode 100644 index 000000000..57e950666 --- /dev/null +++ b/src/main/java/interface_adapter/login/LoginController.java @@ -0,0 +1,28 @@ +package interface_adapter.login; + +import use_case.login.LoginInputBoundary; +import use_case.login.LoginInputData; + +/** + * The controller for the Login Use Case. + */ +public class LoginController { + + private final LoginInputBoundary loginUseCaseInteractor; + + public LoginController(LoginInputBoundary loginUseCaseInteractor) { + this.loginUseCaseInteractor = loginUseCaseInteractor; + } + + /** + * Executes the Login Use Case. + * @param username the username of the user logging in + * @param password the password of the user logging in + */ + public void execute(String username, String password) { + final LoginInputData loginInputData = new LoginInputData( + username, password); + + loginUseCaseInteractor.execute(loginInputData); + } +} diff --git a/src/main/java/use_case/login/LoginInputBoundary.java b/src/main/java/use_case/login/LoginInputBoundary.java index 15010279f..0b59f2a4f 100644 --- a/src/main/java/use_case/login/LoginInputBoundary.java +++ b/src/main/java/use_case/login/LoginInputBoundary.java @@ -1,5 +1,12 @@ package use_case.login; +/** + * Input Boundary for actions which are related to logging in. + */ public interface LoginInputBoundary { + /** + * Executes the login use case. + * @param loginInputData the input data + */ void execute(LoginInputData loginInputData); } diff --git a/src/main/java/use_case/login/LoginInputData.java b/src/main/java/use_case/login/LoginInputData.java index c2050eb4c..fceeb3c40 100644 --- a/src/main/java/use_case/login/LoginInputData.java +++ b/src/main/java/use_case/login/LoginInputData.java @@ -1,5 +1,8 @@ package use_case.login; +/** + * The Input Data for the Login Use Case. + */ public class LoginInputData { private final String username; @@ -13,6 +16,7 @@ public LoginInputData(String username, String password) { public String getUsername() { return username; } + public String getPassword() { return password; } diff --git a/src/main/java/use_case/login/LoginInteractor.java b/src/main/java/use_case/login/LoginInteractor.java index eab95611f..2ed57f690 100644 --- a/src/main/java/use_case/login/LoginInteractor.java +++ b/src/main/java/use_case/login/LoginInteractor.java @@ -2,6 +2,9 @@ import entity.User; +/** + * The Login Interactor. + */ public class LoginInteractor implements LoginInputBoundary { private final LoginUserDataAccessInterface userDataAccessObject; private final LoginOutputBoundary loginPresenter; diff --git a/src/main/java/use_case/login/LoginOutputBoundary.java b/src/main/java/use_case/login/LoginOutputBoundary.java index eff2b9faa..c835b4bc0 100644 --- a/src/main/java/use_case/login/LoginOutputBoundary.java +++ b/src/main/java/use_case/login/LoginOutputBoundary.java @@ -1,7 +1,17 @@ package use_case.login; +/** + * The output boundary for the Login Use Case. + */ public interface LoginOutputBoundary { - void prepareSuccessView(LoginOutputData loginoutputdata); - + /** + * Prepares the success view for the Login Use Case. + * @param outputData the output data + */ + void prepareSuccessView(LoginOutputData outputData); + /** + * Prepares the failure view for the Login Use Case. + * @param errorMessage the explanation of the failure + */ void prepareFailView(String errorMessage); } diff --git a/src/main/java/use_case/login/LoginOutputData.java b/src/main/java/use_case/login/LoginOutputData.java index 9814ea504..1ef2fbef5 100644 --- a/src/main/java/use_case/login/LoginOutputData.java +++ b/src/main/java/use_case/login/LoginOutputData.java @@ -1,5 +1,8 @@ package use_case.login; +/** + * Output Data for the Login Use Case. + */ public class LoginOutputData { private final String username; private final boolean useCaseFailed; @@ -16,4 +19,4 @@ public String getUsername() { public boolean isUseCaseFailed() { return useCaseFailed; } -} \ No newline at end of file +} diff --git a/src/main/java/use_case/login/LoginUserDataAccessInterface.java b/src/main/java/use_case/login/LoginUserDataAccessInterface.java index a9c256ac9..4d4e631d2 100644 --- a/src/main/java/use_case/login/LoginUserDataAccessInterface.java +++ b/src/main/java/use_case/login/LoginUserDataAccessInterface.java @@ -2,12 +2,29 @@ import entity.User; -public class LoginUserDataAccessInterface { +/** + * DAO for the Login Use Case. + */ +public interface LoginUserDataAccessInterface { + /** + * Checks if the given username exists. + * @param username the username to look for + * @return true if a user with the given username exists; false otherwise + */ boolean existsByName(String username); + /** + * Saves the user. + * @param user the user to save + */ void save(User user); + /** + * Returns the user with the given username. + * @param username the username to look up + * @return the user with the given username + */ User get(String username); void setCurrentUser(String name); diff --git a/src/main/java/use_case/signup/SignupInputBoundary.java b/src/main/java/use_case/signup/SignupInputBoundary.java new file mode 100644 index 000000000..1cb69e02e --- /dev/null +++ b/src/main/java/use_case/signup/SignupInputBoundary.java @@ -0,0 +1,18 @@ +package use_case.signup; + +/** + * Input Boundary for actions which are related to signing up. + */ +public interface SignupInputBoundary { + + /** + * Executes the signup use case. + * @param signupInputData the input data + */ + void execute(SignupInputData signupInputData); + + /** + * Executes the switch to login view use case. + */ + void switchToLoginView(); +} diff --git a/src/main/java/use_case/signup/SignupInputData.java b/src/main/java/use_case/signup/SignupInputData.java new file mode 100644 index 000000000..86c5e8abc --- /dev/null +++ b/src/main/java/use_case/signup/SignupInputData.java @@ -0,0 +1,29 @@ +package use_case.signup; + +/** + * The Input Data for the Signup Use Case. + */ +public class SignupInputData { + + private final String username; + private final String password; + private final String repeatPassword; + + public SignupInputData(String username, String password, String repeatPassword) { + this.username = username; + this.password = password; + this.repeatPassword = repeatPassword; + } + + String getUsername() { + return username; + } + + String getPassword() { + return password; + } + + public String getRepeatPassword() { + return repeatPassword; + } +} diff --git a/src/main/java/use_case/signup/SignupInteractor.java b/src/main/java/use_case/signup/SignupInteractor.java new file mode 100644 index 000000000..ff2b012d1 --- /dev/null +++ b/src/main/java/use_case/signup/SignupInteractor.java @@ -0,0 +1,42 @@ +package use_case.signup; + +import entity.User; + +/** + * The Signup Interactor. + */ +public class SignupInteractor implements SignupInputBoundary { + private final SignupUserDataAccessInterface userDataAccessObject; + private final SignupOutputBoundary userPresenter; + private final UserFactory userFactory; + + public SignupInteractor(SignupUserDataAccessInterface signupDataAccessInterface, + SignupOutputBoundary signupOutputBoundary, + UserFactory userFactory) { + this.userDataAccessObject = signupDataAccessInterface; + this.userPresenter = signupOutputBoundary; + this.userFactory = userFactory; + } + + @Override + public void execute(SignupInputData signupInputData) { + if (userDataAccessObject.existsByName(signupInputData.getUsername())) { + userPresenter.prepareFailView("User already exists."); + } + else if (!signupInputData.getPassword().equals(signupInputData.getRepeatPassword())) { + userPresenter.prepareFailView("Passwords don't match."); + } + else { + final User user = userFactory.create(signupInputData.getUsername(), signupInputData.getPassword()); + userDataAccessObject.save(user); + + final SignupOutputData signupOutputData = new SignupOutputData(user.getName(), false); + userPresenter.prepareSuccessView(signupOutputData); + } + } + + @Override + public void switchToLoginView() { + userPresenter.switchToLoginView(); + } +} diff --git a/src/main/java/use_case/signup/SignupOutputBoundary.java b/src/main/java/use_case/signup/SignupOutputBoundary.java new file mode 100644 index 000000000..314376b93 --- /dev/null +++ b/src/main/java/use_case/signup/SignupOutputBoundary.java @@ -0,0 +1,24 @@ +package use_case.signup; + +/** + * The output boundary for the Signup Use Case. + */ +public interface SignupOutputBoundary { + + /** + * Prepares the success view for the Signup Use Case. + * @param outputData the output data + */ + void prepareSuccessView(SignupOutputData outputData); + + /** + * Prepares the failure view for the Signup Use Case. + * @param errorMessage the explanation of the failure + */ + void prepareFailView(String errorMessage); + + /** + * Switches to the Login View. + */ + void switchToLoginView(); +} diff --git a/src/main/java/use_case/signup/SignupOutputData.java b/src/main/java/use_case/signup/SignupOutputData.java new file mode 100644 index 000000000..6dc74d2fb --- /dev/null +++ b/src/main/java/use_case/signup/SignupOutputData.java @@ -0,0 +1,24 @@ +package use_case.signup; + +/** + * Output Data for the Signup Use Case. + */ +public class SignupOutputData { + + private final String username; + + private final boolean useCaseFailed; + + public SignupOutputData(String username, boolean useCaseFailed) { + this.username = username; + this.useCaseFailed = useCaseFailed; + } + + public String getUsername() { + return username; + } + + public boolean isUseCaseFailed() { + return useCaseFailed; + } +} diff --git a/src/main/java/use_case/signup/SignupUserDataAccessInterface.java b/src/main/java/use_case/signup/SignupUserDataAccessInterface.java new file mode 100644 index 000000000..b9d60f585 --- /dev/null +++ b/src/main/java/use_case/signup/SignupUserDataAccessInterface.java @@ -0,0 +1,22 @@ +package use_case.signup; + +import entity.User; + +/** + * DAO for the Signup Use Case. + */ +public interface SignupUserDataAccessInterface { + + /** + * Checks if the given username exists. + * @param username the username to look for + * @return true if a user with the given username exists; false otherwise + */ + boolean existsByName(String username); + + /** + * Saves the user. + * @param user the user to save + */ + void save(User user); +} From 79434fae990bce99cc27fb728d0bfd80f257e547 Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Fri, 22 Nov 2024 16:47:26 -0500 Subject: [PATCH 029/125] UserFactory deletion --- src/main/java/entity/UserFactory.java | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 src/main/java/entity/UserFactory.java diff --git a/src/main/java/entity/UserFactory.java b/src/main/java/entity/UserFactory.java deleted file mode 100644 index d2e74c885..000000000 --- a/src/main/java/entity/UserFactory.java +++ /dev/null @@ -1,16 +0,0 @@ -package entity; - -/** - * Factory for creating users. - */ -public class UserFactory { - /** - * Creates a new User. - * @param name the name of the new user - * @param password the password of the new user - * @return the new user - */ - public User create(String name, String password) { - return new User(name, password); - } -} From 3f08528d241933625854793f137bc12716866368 Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Fri, 22 Nov 2024 16:50:35 -0500 Subject: [PATCH 030/125] SignupInteractor Updated --- src/main/java/use_case/signup/SignupInteractor.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/use_case/signup/SignupInteractor.java b/src/main/java/use_case/signup/SignupInteractor.java index ff2b012d1..2cd2ed429 100644 --- a/src/main/java/use_case/signup/SignupInteractor.java +++ b/src/main/java/use_case/signup/SignupInteractor.java @@ -8,14 +8,11 @@ public class SignupInteractor implements SignupInputBoundary { private final SignupUserDataAccessInterface userDataAccessObject; private final SignupOutputBoundary userPresenter; - private final UserFactory userFactory; public SignupInteractor(SignupUserDataAccessInterface signupDataAccessInterface, - SignupOutputBoundary signupOutputBoundary, - UserFactory userFactory) { + SignupOutputBoundary signupOutputBoundary) { this.userDataAccessObject = signupDataAccessInterface; this.userPresenter = signupOutputBoundary; - this.userFactory = userFactory; } @Override @@ -27,7 +24,7 @@ else if (!signupInputData.getPassword().equals(signupInputData.getRepeatPassword userPresenter.prepareFailView("Passwords don't match."); } else { - final User user = userFactory.create(signupInputData.getUsername(), signupInputData.getPassword()); + final User user = new User(signupInputData.getUsername(), signupInputData.getPassword()); userDataAccessObject.save(user); final SignupOutputData signupOutputData = new SignupOutputData(user.getName(), false); From fb10baf5da4496a176b0d080003bce1602f7cda0 Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Fri, 22 Nov 2024 18:09:04 -0500 Subject: [PATCH 031/125] Login Interface --- .../data_access/ChessDataAccessObject.java | 39 +++++++++++++++- .../login/LoginPresenter.java | 45 +++++++++++++++++++ .../interface_adapter/login/LoginState.java | 36 +++++++++++++++ .../login/LoginViewModel.java | 16 +++++++ 4 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 src/main/java/interface_adapter/login/LoginPresenter.java create mode 100644 src/main/java/interface_adapter/login/LoginState.java create mode 100644 src/main/java/interface_adapter/login/LoginViewModel.java diff --git a/src/main/java/data_access/ChessDataAccessObject.java b/src/main/java/data_access/ChessDataAccessObject.java index 41d9b97ed..2f1628b5b 100644 --- a/src/main/java/data_access/ChessDataAccessObject.java +++ b/src/main/java/data_access/ChessDataAccessObject.java @@ -1,5 +1,42 @@ package data_access; -public class ChessDataAccessObject { +import java.util.HashMap; +import java.util.Map; +import entity.User; +import use_case.login.LoginUserDataAccessInterface; +import use_case.signup.SignupUserDataAccessInterface; + +/** + * The DAO for user data. + */ +public class ChessDataAccessObject implements LoginUserDataAccessInterface, SignupUserDataAccessInterface { + + private final Map users = new HashMap<>(); + private String currentUser; + + @Override + public User get(String username) { + return users.get(username); + } + + @Override + public void setCurrentUser(String name) { + this.currentUser = name; + } + + @Override + public String getCurrentUser() { + return currentUser; + } + + @Override + public boolean existsByName(String username) { + return users.containsKey(username); + } + + @Override + public void save(User user) { + users.put(user.getName(), user); + } } diff --git a/src/main/java/interface_adapter/login/LoginPresenter.java b/src/main/java/interface_adapter/login/LoginPresenter.java new file mode 100644 index 000000000..087996fd2 --- /dev/null +++ b/src/main/java/interface_adapter/login/LoginPresenter.java @@ -0,0 +1,45 @@ +package interface_adapter.login; + +import interface_adapter.ViewManagerModel; +import interface_adapter.logged_in.LoggedInState; +import interface_adapter.logged_in.LoggedInViewModel; +import use_case.login.LoginOutputBoundary; +import use_case.login.LoginOutputData; + +/** + * The Presenter for the Login Use Case. + */ +public class LoginPresenter implements LoginOutputBoundary { + + private final LoginViewModel loginViewModel; + private final LoggedInViewModel loggedInViewModel; + private final ViewManagerModel viewManagerModel; + + public LoginPresenter(ViewManagerModel viewManagerModel, + LoggedInViewModel loggedInViewModel, + LoginViewModel loginViewModel) { + this.viewManagerModel = viewManagerModel; + this.loggedInViewModel = loggedInViewModel; + this.loginViewModel = loginViewModel; + } + + @Override + public void prepareSuccessView(LoginOutputData response) { + // On success, switch to the logged in view. + + final LoggedInState loggedInState = loggedInViewModel.getState(); + loggedInState.setUsername(response.getUsername()); + this.loggedInViewModel.setState(loggedInState); + this.loggedInViewModel.firePropertyChanged(); + + this.viewManagerModel.setState(loggedInViewModel.getViewName()); + this.viewManagerModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String error) { + final LoginState loginState = loginViewModel.getState(); + loginState.setLoginError(error); + loginViewModel.firePropertyChanged(); + } +} diff --git a/src/main/java/interface_adapter/login/LoginState.java b/src/main/java/interface_adapter/login/LoginState.java new file mode 100644 index 000000000..11117fe42 --- /dev/null +++ b/src/main/java/interface_adapter/login/LoginState.java @@ -0,0 +1,36 @@ +package interface_adapter.login; + +/** + * The state for the Login View Model. + */ +public class LoginState { + private String username = ""; + private String loginError; + private String password = ""; + + public String getUsername() { + return username; + } + + public String getLoginError() { + return loginError; + } + + public String getPassword() { + return password; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setLoginError(String usernameError) { + this.loginError = usernameError; + } + + public void setPassword(String password) { + this.password = password; + } + +} + diff --git a/src/main/java/interface_adapter/login/LoginViewModel.java b/src/main/java/interface_adapter/login/LoginViewModel.java new file mode 100644 index 000000000..b24171c03 --- /dev/null +++ b/src/main/java/interface_adapter/login/LoginViewModel.java @@ -0,0 +1,16 @@ +package interface_adapter.login; + +import interface_adapter.ViewModel; + +/** + * The View Model for the Login View. + */ +public class LoginViewModel extends ViewModel { + + public LoginViewModel() { + super("log in"); + setState(new LoginState()); + } + +} + From 66bbedf9d06c4027ffea6d30579b1eecfff207ab Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Fri, 22 Nov 2024 18:30:05 -0500 Subject: [PATCH 032/125] LoggedIn Interface --- .../logged_in/LoggedInPresenter.java | 31 +++++++++++++++++++ .../logged_in/LoggedInState.java | 26 ++++++++++++++++ .../logged_in/LoggedInViewModel.java | 15 +++++++++ 3 files changed, 72 insertions(+) create mode 100644 src/main/java/interface_adapter/logged_in/LoggedInPresenter.java create mode 100644 src/main/java/interface_adapter/logged_in/LoggedInState.java create mode 100644 src/main/java/interface_adapter/logged_in/LoggedInViewModel.java diff --git a/src/main/java/interface_adapter/logged_in/LoggedInPresenter.java b/src/main/java/interface_adapter/logged_in/LoggedInPresenter.java new file mode 100644 index 000000000..568f9b209 --- /dev/null +++ b/src/main/java/interface_adapter/logged_in/LoggedInPresenter.java @@ -0,0 +1,31 @@ +package interface_adapter.logged_in; + +import interface_adapter.ViewManagerModel; + +/** + * The Presenter for the Change Password Use Case. + */ +public class LoggedInPresenter { + + private final LoggedInViewModel loggedInViewModel; + private final ViewManagerModel viewManagerModel; + + public LoggedInPresenter(ViewManagerModel viewManagerModel, + LoggedInViewModel loggedInViewModel) { + this.viewManagerModel = viewManagerModel; + this.loggedInViewModel = loggedInViewModel; + } + + public void prepareLoggedInView(String username) { + final LoggedInState state = loggedInViewModel.getState(); + state.setUsername(username); + loggedInViewModel.setState(state); + loggedInViewModel.firePropertyChanged(); + + } + + public void prepareFailView(String error) { + loggedInViewModel.setState(new LoggedInState()); + loggedInViewModel.firePropertyChanged(); + } +} diff --git a/src/main/java/interface_adapter/logged_in/LoggedInState.java b/src/main/java/interface_adapter/logged_in/LoggedInState.java new file mode 100644 index 000000000..22e0209f5 --- /dev/null +++ b/src/main/java/interface_adapter/logged_in/LoggedInState.java @@ -0,0 +1,26 @@ +package interface_adapter.logged_in; + +/** + * The State information representing the logged-in user. + */ +public class LoggedInState { + private String username = ""; + + public LoggedInState(LoggedInState copy) { + username = copy.username; + } + + // Because of the previous copy constructor, the default constructor must be explicit. + public LoggedInState() { + + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + +} diff --git a/src/main/java/interface_adapter/logged_in/LoggedInViewModel.java b/src/main/java/interface_adapter/logged_in/LoggedInViewModel.java new file mode 100644 index 000000000..ba0184f58 --- /dev/null +++ b/src/main/java/interface_adapter/logged_in/LoggedInViewModel.java @@ -0,0 +1,15 @@ +package interface_adapter.logged_in; + +import interface_adapter.ViewModel; + +/** + * The View Model for the Logged In View. + */ +public class LoggedInViewModel extends ViewModel { + + public LoggedInViewModel() { + super("logged in"); + setState(new LoggedInState()); + } + +} From 875ee6c712b46d62cf4c3aef409611429cfdec0b Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Sun, 24 Nov 2024 14:10:39 -0500 Subject: [PATCH 033/125] 'DailPuzzleDataAccessInterface.java' & 'ChessDataAccessObject.java' & created. Excute method of 'MoveInputBoundary.java' & 'MoveInteractor.java' rename to 'excute'. Minimal 'MovePresenter.java' implemented (without logic). IMPORTANT!!: 'Game' instancevariable deleted from 'MoveInteractor.java' (need further discussion, because i think it's not 'MoveInteractor's job to initiate a 'game'). 'MainChessApp.java' and associate 'ChessAppBuilder.java' implemented, Default chessboard view can now be seen by running 'MainChessApp.java' --- src/main/java/app/ChessAppBuilder.java | 72 +++++++++++++++++++ src/main/java/app/MainChessApp.java | 16 ++++- .../data_access/ChessDataAccessObject.java | 9 ++- src/main/java/entity/ChessPiece.java | 3 + .../move/MoveController.java | 2 +- .../interface_adapter/move/MovePresenter.java | 15 +++- .../DailyPuzzleDataAccessInterface.java | 5 +- .../java/use_case/move/MoveInputBoundary.java | 2 +- .../java/use_case/move/MoveInteractor.java | 18 +++-- src/main/java/view/ChessBoardView.java | 6 +- src/test/java/view/ChessBoardViewTest.java | 16 ++++- 11 files changed, 148 insertions(+), 16 deletions(-) diff --git a/src/main/java/app/ChessAppBuilder.java b/src/main/java/app/ChessAppBuilder.java index 75241c2e6..d19f086c6 100644 --- a/src/main/java/app/ChessAppBuilder.java +++ b/src/main/java/app/ChessAppBuilder.java @@ -1,4 +1,76 @@ package app; +import javax.swing.JFrame; +import javax.swing.WindowConstants; + +import data_access.ChessDataAccessObject; +import interface_adapter.ViewManagerModel; +import interface_adapter.move.MoveController; +import interface_adapter.move.MovePresenter; +import interface_adapter.move.MoveViewModel; +import use_case.move.MoveInteractor; +import use_case.move.MoveOutPutBoundary; +import view.ChessBoardView; + +/** + * Builder for the Note Application. + */ public class ChessAppBuilder { + public static final int HEIGHT = 800; + public static final int WIDTH = 800; + // TODO change to ChessDataAccessInterface once implemented + private ChessDataAccessObject chessDataAccessObject; + private MoveViewModel moveViewModel = new MoveViewModel(); + private final ViewManagerModel viewManagerModel = new ViewManagerModel(); + private ChessBoardView chessBoardView; + private MoveInteractor moveInteractor; + + /** + * Set the ChessDAO to be used in this application. + * @param chessDataAccess the DAO to use + * @return this builder + */ + public ChessAppBuilder addChessDAO(ChessDataAccessObject chessDataAccess) { + chessDataAccessObject = chessDataAccess; + return this; + } + + /** + * Creates the objects for the Move Use Case and connects the ChessBoardView to Move controller. + * @return this builder + */ + public ChessAppBuilder addMoveUseCase() { + final MoveOutPutBoundary moveOutPutBoundary = new MovePresenter(moveViewModel, viewManagerModel); + moveInteractor = new MoveInteractor( + chessDataAccessObject, moveOutPutBoundary); + + final MoveController moveController = new MoveController(moveInteractor); + chessBoardView.setMoveController(moveController); + return this; + } + + /** + * Creates the ChessBoardView and underlying MoveViewModel. + * @return this builder + */ + public ChessAppBuilder addMoveView() { + moveViewModel = new MoveViewModel(); + final MoveController moveController = new MoveController(moveInteractor); + chessBoardView = new ChessBoardView(moveViewModel, moveController); + return this; + } + + /** + * Builds the app. + * @return the JFrame for the app + */ + public JFrame build() { + final JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.setTitle("Chess App"); + frame.setSize(WIDTH, HEIGHT); + + frame.add(chessBoardView); + return frame; + } } diff --git a/src/main/java/app/MainChessApp.java b/src/main/java/app/MainChessApp.java index 55c210584..54aa50c4e 100644 --- a/src/main/java/app/MainChessApp.java +++ b/src/main/java/app/MainChessApp.java @@ -1,11 +1,25 @@ package app; import data_access.ChessDataAccessObject; -import use_case.note.NoteDataAccessInterface; +/** + * This is the main chess app. + */ public class MainChessApp { + /** + * Main method. + * @param args commandline arguments + */ public static void main(String[] args) { + // TODO change to ChessDataAccessInterface once implemented + final ChessDataAccessObject chessDataAccessObject = new ChessDataAccessObject(); + + final ChessAppBuilder chessAppBuilder = new ChessAppBuilder(); + chessAppBuilder.addChessDAO(chessDataAccessObject) + .addMoveView() + .addMoveUseCase().build().setVisible(true); + } } diff --git a/src/main/java/data_access/ChessDataAccessObject.java b/src/main/java/data_access/ChessDataAccessObject.java index 6f1a2a880..af75a6952 100644 --- a/src/main/java/data_access/ChessDataAccessObject.java +++ b/src/main/java/data_access/ChessDataAccessObject.java @@ -1,4 +1,11 @@ package data_access; -public class ChessDataAccessObject { +import use_case.daily_puzzle.DailyPuzzleDataAccessInterface; +import use_case.move.MoveDataAccessInterface; + +/** + * The DAO to access lichess API. + * related use case are 'daily Puzzle' & 'Move' + */ +public class ChessDataAccessObject implements MoveDataAccessInterface, DailyPuzzleDataAccessInterface { } diff --git a/src/main/java/entity/ChessPiece.java b/src/main/java/entity/ChessPiece.java index 5b1f9715f..73dbea9d2 100644 --- a/src/main/java/entity/ChessPiece.java +++ b/src/main/java/entity/ChessPiece.java @@ -2,6 +2,9 @@ import java.util.ArrayList; +/** + * The abstract class of all chess piece. + */ public abstract class ChessPiece { private String color; private ArrayList position; diff --git a/src/main/java/interface_adapter/move/MoveController.java b/src/main/java/interface_adapter/move/MoveController.java index 0b8a038fd..6a74f5ccd 100644 --- a/src/main/java/interface_adapter/move/MoveController.java +++ b/src/main/java/interface_adapter/move/MoveController.java @@ -25,6 +25,6 @@ public void onClick(Integer xcord, Integer ycord) { position.add(xcord); position.add(ycord); final MoveInputdata moveInputdata = new MoveInputdata(position); - moveInteractor.handleClick(moveInputdata); + moveInteractor.execute(moveInputdata); } } diff --git a/src/main/java/interface_adapter/move/MovePresenter.java b/src/main/java/interface_adapter/move/MovePresenter.java index 2161e5c15..f4d5666bc 100644 --- a/src/main/java/interface_adapter/move/MovePresenter.java +++ b/src/main/java/interface_adapter/move/MovePresenter.java @@ -1,4 +1,17 @@ package interface_adapter.move; -public class MovePresenter { +import interface_adapter.ViewManagerModel; +import use_case.move.MoveOutPutBoundary; + +/** + * The presenter for Move use case. + */ +public class MovePresenter implements MoveOutPutBoundary { + private final MoveViewModel moveViewModel; + private final ViewManagerModel viewManagerModel; + + public MovePresenter(MoveViewModel moveViewModel, ViewManagerModel viewManagerModel) { + this.moveViewModel = moveViewModel; + this.viewManagerModel = viewManagerModel; + } } diff --git a/src/main/java/use_case/daily_puzzle/DailyPuzzleDataAccessInterface.java b/src/main/java/use_case/daily_puzzle/DailyPuzzleDataAccessInterface.java index 5715a8ab0..d905ee1a8 100644 --- a/src/main/java/use_case/daily_puzzle/DailyPuzzleDataAccessInterface.java +++ b/src/main/java/use_case/daily_puzzle/DailyPuzzleDataAccessInterface.java @@ -1,4 +1,7 @@ package use_case.daily_puzzle; -public class DailyPuzzleDataAccessInterface { +/** + * DAO for Daily Puzzle use case. + */ +public interface DailyPuzzleDataAccessInterface { } diff --git a/src/main/java/use_case/move/MoveInputBoundary.java b/src/main/java/use_case/move/MoveInputBoundary.java index 1b4a4242e..5f3cd8617 100644 --- a/src/main/java/use_case/move/MoveInputBoundary.java +++ b/src/main/java/use_case/move/MoveInputBoundary.java @@ -8,5 +8,5 @@ public interface MoveInputBoundary { * Executes the move use case. * @param moveInputData the input data */ - void handleClick(MoveInputdata moveInputData); + void execute(MoveInputdata moveInputData); } diff --git a/src/main/java/use_case/move/MoveInteractor.java b/src/main/java/use_case/move/MoveInteractor.java index ce91ecb5d..bbf96feed 100644 --- a/src/main/java/use_case/move/MoveInteractor.java +++ b/src/main/java/use_case/move/MoveInteractor.java @@ -1,21 +1,25 @@ package use_case.move; +import entity.Game; /** * Move interactor who handles the business logic of move. */ public class MoveInteractor implements MoveInputBoundary { - private entity.Game game; + private final MoveDataAccessInterface moveDataAccessObject; + private final MoveOutPutBoundary moveOutPutBoundary; - public MoveInteractor(entity.Game game) { - this.game = game; + public MoveInteractor(MoveDataAccessInterface moveDataAccessObject, + MoveOutPutBoundary moveOutPutBoundary) { + this.moveDataAccessObject = moveDataAccessObject; + this.moveOutPutBoundary = moveOutPutBoundary; } - public boolean isvalidmove() { - // check if this move is valid - } +// private boolean isvalidmove() { +// // check if this move is valid +// } @Override - public void handleClick(MoveInputdata position) { + public void execute(MoveInputdata position) { // Starting point of this class } diff --git a/src/main/java/view/ChessBoardView.java b/src/main/java/view/ChessBoardView.java index 89a4b0bff..8ec2d98b9 100644 --- a/src/main/java/view/ChessBoardView.java +++ b/src/main/java/view/ChessBoardView.java @@ -18,7 +18,7 @@ public class ChessBoardView extends JPanel implements ActionListener, PropertyCh private final String viewName = "Chess Board"; private final MoveViewModel moveViewModel; - private final MoveController moveController; + private MoveController moveController; public ChessBoardView(MoveViewModel moveViewModel, MoveController moveController) { this.moveViewModel = moveViewModel; @@ -58,6 +58,10 @@ public ChessBoardView(MoveViewModel moveViewModel, MoveController moveController } + public void setMoveController(MoveController moveController) { + this.moveController = moveController; + } + @Override public void actionPerformed(ActionEvent e) { diff --git a/src/test/java/view/ChessBoardViewTest.java b/src/test/java/view/ChessBoardViewTest.java index 2b6b8ca1e..b12f03838 100644 --- a/src/test/java/view/ChessBoardViewTest.java +++ b/src/test/java/view/ChessBoardViewTest.java @@ -1,10 +1,17 @@ package view; +import data_access.ChessDataAccessObject; +import entity.Board; +import entity.Game; +import interface_adapter.ViewManagerModel; import interface_adapter.move.MoveController; +import interface_adapter.move.MovePresenter; import interface_adapter.move.MoveViewModel; +import use_case.move.MoveDataAccessInterface; +import use_case.move.MoveInteractor; +import use_case.move.MoveOutPutBoundary; import javax.swing.*; -import java.awt.*; public class ChessBoardViewTest { @@ -15,7 +22,12 @@ public static void main(String[] args) { frame.setSize(800, 800); MoveViewModel TestModel = new MoveViewModel(); - MoveController TestController = new MoveController(); + MoveDataAccessInterface moveDataAccessObject = new ChessDataAccessObject(); + MoveViewModel moveViewModel = new MoveViewModel(); + ViewManagerModel viewManagerModel = new ViewManagerModel(); + MoveOutPutBoundary movePresenter = new MovePresenter(moveViewModel, viewManagerModel); + MoveInteractor TestInteractor = new MoveInteractor(moveDataAccessObject, movePresenter); + MoveController TestController = new MoveController(TestInteractor); ChessBoardView TestView = new ChessBoardView(TestModel, TestController); From da5a37f932a3b9595a4ffc456c98f2f694efc9ea Mon Sep 17 00:00:00 2001 From: DMA <1670639177@qq.com> Date: Mon, 25 Nov 2024 16:31:16 -0500 Subject: [PATCH 034/125] 'ChessBoardView.java''s 'actionPerformed' method implemented. It can now print the position of buttom cliked(bottom left: (0,0); top right: (7,7)) --- src/main/java/view/ChessBoardView.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/java/view/ChessBoardView.java b/src/main/java/view/ChessBoardView.java index 8ec2d98b9..3d2f86df7 100644 --- a/src/main/java/view/ChessBoardView.java +++ b/src/main/java/view/ChessBoardView.java @@ -1,16 +1,18 @@ package view; -import interface_adapter.move.MoveController; -import interface_adapter.move.MoveViewModel; - -import javax.swing.*; -import javax.swing.text.View; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import interface_adapter.move.MoveController; +import interface_adapter.move.MoveViewModel; + /** * The view of actual chess game. */ @@ -33,6 +35,9 @@ public ChessBoardView(MoveViewModel moveViewModel, MoveController moveController for (int row = 0; row < 8; row++) { for (int col = 0; col < 8; col++) { JButton button = new JButton(); + final String string_row = String.valueOf(Math.abs(row - 7)); + final String string_col = String.valueOf(col); + button.setActionCommand(string_col + "," + string_row); // Set background color to alternate between black and white if ((row + col) % 2 == 0) { @@ -49,7 +54,7 @@ public ChessBoardView(MoveViewModel moveViewModel, MoveController moveController button.setFont(new Font("Serif", Font.BOLD, 36)); } - button.setFocusPainted(false); + button.setFocusPainted(true); button.addActionListener(this); this.add(button); @@ -64,7 +69,7 @@ public void setMoveController(MoveController moveController) { @Override public void actionPerformed(ActionEvent e) { - + System.out.println(e.getActionCommand()); } @Override From 502f57d418d0ed535018607520c7b894437ada1c Mon Sep 17 00:00:00 2001 From: 207moment Date: Mon, 25 Nov 2024 16:41:55 -0500 Subject: [PATCH 035/125] Implementation of API access methods and interfaces, also cleanup of the daily puzzle interactor. --- .../data_access/PuzzleDataAccessObject.java | 67 +++++++++++++++++++ .../daily_puzzle/DailyPuzzleInteractor.java | 42 +++--------- .../DailyPuzzleOutputBoundary.java | 4 +- .../daily_puzzle/DailyPuzzleOutputData.java | 8 +-- .../daily_puzzle/PuzzleAccessException.java | 8 +++ .../PuzzleDataAccessInterface.java | 26 +++++++ 6 files changed, 118 insertions(+), 37 deletions(-) create mode 100644 src/main/java/data_access/PuzzleDataAccessObject.java create mode 100644 src/main/java/use_case/daily_puzzle/PuzzleAccessException.java create mode 100644 src/main/java/use_case/daily_puzzle/PuzzleDataAccessInterface.java diff --git a/src/main/java/data_access/PuzzleDataAccessObject.java b/src/main/java/data_access/PuzzleDataAccessObject.java new file mode 100644 index 000000000..0a2f1f6af --- /dev/null +++ b/src/main/java/data_access/PuzzleDataAccessObject.java @@ -0,0 +1,67 @@ +package data_access; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import use_case.daily_puzzle.PuzzleAccessException; +import use_case.daily_puzzle.PuzzleDataAccessInterface; + +import java.io.IOException; +import java.util.ArrayList; + +public class PuzzleDataAccessObject implements PuzzleDataAccessInterface { + private static final int SUCCESS_CODE = 200; + private static final String LICHESS_PUZZLE_URL = "https://lichess.org/api/puzzle/"; + private static final String DAILY_PUZZLE_URL = "daily"; + private static String PUZZLE_FROM_ID_URL; + + public ArrayList getDaily() throws PuzzleAccessException { + final OkHttpClient client = new OkHttpClient().newBuilder().build(); + final Request request = new Request.Builder().url(LICHESS_PUZZLE_URL + DAILY_PUZZLE_URL).build(); + ArrayList output = null; + + try { + final Response response = client.newCall(request).execute(); + + final JSONObject responseBody = new JSONObject(response.body().string()); + + JSONObject puzzle = responseBody.getJSONObject("puzzle"); + JSONArray solution = puzzle.getJSONArray("solution"); + output.add(puzzle.getString("id")); + for (int i = 0; i < solution.length(); i++) { + output.add(solution.getString(i)); + } + } + catch (final IOException | JSONException e) { + throw new PuzzleAccessException(e.getMessage()); + } + return output; + } + + @Override + public ArrayList fetchPuzzle(String id) throws PuzzleAccessException { + final OkHttpClient client = new OkHttpClient().newBuilder().build(); + final Request request = new Request.Builder().url(LICHESS_PUZZLE_URL + PUZZLE_FROM_ID_URL).build(); + ArrayList output = null; + + try { + final Response response = client.newCall(request).execute(); + + final JSONObject responseBody = new JSONObject(response.body().string()); + + JSONArray solution = responseBody.getJSONArray("solution"); + output.add(responseBody.getJSONObject("game").getString("pgn")); + for (int i = 0; i < solution.length(); i++) { + output.add(solution.getString(i)); + } + } + catch (final IOException | JSONException e) { + throw new PuzzleAccessException(e.getMessage()); + } + return output; + } +} diff --git a/src/main/java/use_case/daily_puzzle/DailyPuzzleInteractor.java b/src/main/java/use_case/daily_puzzle/DailyPuzzleInteractor.java index 8e9508569..0ec891688 100644 --- a/src/main/java/use_case/daily_puzzle/DailyPuzzleInteractor.java +++ b/src/main/java/use_case/daily_puzzle/DailyPuzzleInteractor.java @@ -1,28 +1,17 @@ package use_case.daily_puzzle; -import java.io.IOException; - -import org.json.JSONException; -import org.json.JSONObject; - -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; +import java.util.ArrayList; /** * The daily puzzle interactor. */ public class DailyPuzzleInteractor { - private static final String LICHESS_URL = "https://lichess.org/api/puzzle/daily"; - private static final String TOKEN = "token"; - private final DailyPuzzleOutputBoundary puzzlePresenter; - - public DailyPuzzleInteractor(DailyPuzzleOutputBoundary dailyPuzzleOutputBoundary) { - this.puzzlePresenter = dailyPuzzleOutputBoundary; - } + private final PuzzleDataAccessInterface dailyPuzzleDataAccessInterface; + private final DailyPuzzleOutputBoundary dailyPuzzleOutputBoundary; - public static String getToken() { - return System.getenv(TOKEN); + public DailyPuzzleInteractor(PuzzleDataAccessInterface dailyPuzzleDataAccessInterface, DailyPuzzleOutputBoundary dailyPuzzleOutputBoundary) { + this.dailyPuzzleDataAccessInterface = dailyPuzzleDataAccessInterface; + this.dailyPuzzleOutputBoundary = dailyPuzzleOutputBoundary; } /** @@ -30,25 +19,14 @@ public static String getToken() { * @throws RuntimeException if API request fails. */ public void execute() { - final OkHttpClient client = new OkHttpClient().newBuilder().build(); - final Request request = new Request.Builder().url(LICHESS_URL).build(); - final JSONObject output; try { - final Response response = client.newCall(request).execute(); - final JSONObject responseBody = new JSONObject(response.body().string()); - System.out.println(responseBody); - output = responseBody; - // placeholder, actual will call the view to make a board with the JSON. + final ArrayList puzzle = dailyPuzzleDataAccessInterface.getDaily(); + dailyPuzzleOutputBoundary.prepareSuccessView(puzzle); } - catch (IOException | JSONException event) { - throw new RuntimeException(event); + catch (Exception e) { + System.out.println("Error: " + e.getMessage()); } - - final DailyPuzzleOutputData outputData = new DailyPuzzleOutputData(output, false); - // fail checks/generating erorr message will come later, just want to see it works first - puzzlePresenter.prepareSuccessView(outputData); - } } diff --git a/src/main/java/use_case/daily_puzzle/DailyPuzzleOutputBoundary.java b/src/main/java/use_case/daily_puzzle/DailyPuzzleOutputBoundary.java index 671590506..eda4276dd 100644 --- a/src/main/java/use_case/daily_puzzle/DailyPuzzleOutputBoundary.java +++ b/src/main/java/use_case/daily_puzzle/DailyPuzzleOutputBoundary.java @@ -1,5 +1,7 @@ package use_case.daily_puzzle; +import java.util.ArrayList; + /** * The output boundary for the Daily Puzzle Use case. */ @@ -9,7 +11,7 @@ public interface DailyPuzzleOutputBoundary { * Prepares the success view for the daily puzzle use case. * @param outputData The puzzle's JSON file */ - void prepareSuccessView(DailyPuzzleOutputData outputData); + void prepareSuccessView(ArrayList outputData); /** * Prepares the fail view for the daily puzzle use case. diff --git a/src/main/java/use_case/daily_puzzle/DailyPuzzleOutputData.java b/src/main/java/use_case/daily_puzzle/DailyPuzzleOutputData.java index fa7cda81f..47c45919c 100644 --- a/src/main/java/use_case/daily_puzzle/DailyPuzzleOutputData.java +++ b/src/main/java/use_case/daily_puzzle/DailyPuzzleOutputData.java @@ -1,22 +1,22 @@ package use_case.daily_puzzle; -import org.json.JSONObject; +import java.util.ArrayList; /** * Output data for the daily puzzle use case. */ public class DailyPuzzleOutputData { - private final JSONObject puzzle; + private final ArrayList puzzle; private final boolean useCaseFailed; - public DailyPuzzleOutputData(JSONObject puzzle, boolean useCaseFailed) { + public DailyPuzzleOutputData(ArrayList puzzle, boolean useCaseFailed) { this.puzzle = puzzle; this.useCaseFailed = useCaseFailed; } - public JSONObject getPuzzle() { + public ArrayList getPuzzle() { return puzzle; } // could change later to be board and this or the interactor will call for board generation. diff --git a/src/main/java/use_case/daily_puzzle/PuzzleAccessException.java b/src/main/java/use_case/daily_puzzle/PuzzleAccessException.java new file mode 100644 index 000000000..360a1371f --- /dev/null +++ b/src/main/java/use_case/daily_puzzle/PuzzleAccessException.java @@ -0,0 +1,8 @@ +package use_case.daily_puzzle; + +/** + * Exception thrown when a puzzle can't be returned. + */ +public class PuzzleAccessException extends Exception { + public PuzzleAccessException(String string) { super(string); } +} \ No newline at end of file diff --git a/src/main/java/use_case/daily_puzzle/PuzzleDataAccessInterface.java b/src/main/java/use_case/daily_puzzle/PuzzleDataAccessInterface.java new file mode 100644 index 000000000..12741b172 --- /dev/null +++ b/src/main/java/use_case/daily_puzzle/PuzzleDataAccessInterface.java @@ -0,0 +1,26 @@ +package use_case.daily_puzzle; + +import java.util.ArrayList; + +/** + * Interface for the Lichess api. + * It consists of methods for fetching a daily puzzle and a puzzle from id. + */ +public interface PuzzleDataAccessInterface { + + /** + * Returns the daily puzzle's id and solutions + * @return The JSONObject corresponding to a puzzle + * @throws PuzzleAccessException if a puzzle cannot be fetched. + */ + ArrayList getDaily() throws PuzzleAccessException; + + /** + * Returns a puzzle's moves and solutions from puzzle id. + * @param id the id of the puzzle. + * @return strings of puzzle setup moves and puzzle solutions. + * @throws PuzzleAccessException If a puzzle cannot be fetched. + */ + ArrayList fetchPuzzle(String id) throws PuzzleAccessException; + +} From f98c078c3048958b2b8900b08e09c4a1bf245238 Mon Sep 17 00:00:00 2001 From: DMA <1670639177@qq.com> Date: Mon, 25 Nov 2024 16:42:27 -0500 Subject: [PATCH 036/125] 'ChessBoardView.java' CheckStyle clean up --- src/main/java/view/ChessBoardView.java | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/main/java/view/ChessBoardView.java b/src/main/java/view/ChessBoardView.java index 3d2f86df7..d3246b346 100644 --- a/src/main/java/view/ChessBoardView.java +++ b/src/main/java/view/ChessBoardView.java @@ -1,6 +1,8 @@ package view; -import java.awt.*; +import java.awt.Color; +import java.awt.Font; +import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; @@ -18,6 +20,9 @@ */ public class ChessBoardView extends JPanel implements ActionListener, PropertyChangeListener { + private final int numRow = 8; + private final int numCol = 8; + private final int fontSize = 36; private final String viewName = "Chess Board"; private final MoveViewModel moveViewModel; private MoveController moveController; @@ -29,15 +34,15 @@ public ChessBoardView(MoveViewModel moveViewModel, MoveController moveController final JLabel titleLabel = new JLabel(MoveViewModel.TITLE_LABEL); - this.setLayout(new GridLayout(8, 8)); + this.setLayout(new GridLayout(numRow, numCol)); // Add buttons to the frame in a chessboard pattern - for (int row = 0; row < 8; row++) { - for (int col = 0; col < 8; col++) { - JButton button = new JButton(); - final String string_row = String.valueOf(Math.abs(row - 7)); - final String string_col = String.valueOf(col); - button.setActionCommand(string_col + "," + string_row); + for (int row = 0; row < numRow; row++) { + for (int col = 0; col < numCol; col++) { + final JButton button = new JButton(); + final String stringRow = String.valueOf(Math.abs(row - 7)); + final String stringCol = String.valueOf(col); + button.setActionCommand(stringCol + "," + stringRow); // Set background color to alternate between black and white if ((row + col) % 2 == 0) { @@ -48,10 +53,10 @@ public ChessBoardView(MoveViewModel moveViewModel, MoveController moveController } // Add pieces to the board - String[][] pieces = moveViewModel.getPieces(); + final String[][] pieces = moveViewModel.getPieces(); if (pieces[row][col] != null) { button.setText(pieces[row][col]); - button.setFont(new Font("Serif", Font.BOLD, 36)); + button.setFont(new Font("Serif", Font.BOLD, fontSize)); } button.setFocusPainted(true); From 24f3d6a58c4a61395865913561363022f718067a Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Mon, 25 Nov 2024 18:18:22 -0500 Subject: [PATCH 037/125] UserDataAccessObject Added --- .../data_access/UserDataAccessObject.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/main/java/data_access/UserDataAccessObject.java diff --git a/src/main/java/data_access/UserDataAccessObject.java b/src/main/java/data_access/UserDataAccessObject.java new file mode 100644 index 000000000..9c9828f00 --- /dev/null +++ b/src/main/java/data_access/UserDataAccessObject.java @@ -0,0 +1,42 @@ +package data_access; + +import java.util.HashMap; +import java.util.Map; + +import entity.User; +import use_case.login.LoginUserDataAccessInterface; +import use_case.signup.SignupUserDataAccessInterface; + +/** + * The DAO for user data. + */ +public class UserDataAccessObject implements LoginUserDataAccessInterface, SignupUserDataAccessInterface { + + private final Map users = new HashMap<>(); + private String currentUser; + + @Override + public User get(String username) { + return users.get(username); + } + + @Override + public void setCurrentUser(String name) { + this.currentUser = name; + } + + @Override + public String getCurrentUser() { + return currentUser; + } + + @Override + public boolean existsByName(String username) { + return users.containsKey(username); + } + + @Override + public void save(User user) { + users.put(user.getName(), user); + } +} From f5855be8614b1aa67f9259153cc8c4d0dd0d3e8d Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Mon, 25 Nov 2024 18:20:18 -0500 Subject: [PATCH 038/125] ChessDataAccessObject -deleted UserDAO part --- .../data_access/ChessDataAccessObject.java | 37 +------------------ 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/src/main/java/data_access/ChessDataAccessObject.java b/src/main/java/data_access/ChessDataAccessObject.java index 2f1628b5b..cd11dbfe0 100644 --- a/src/main/java/data_access/ChessDataAccessObject.java +++ b/src/main/java/data_access/ChessDataAccessObject.java @@ -1,42 +1,7 @@ package data_access; -import java.util.HashMap; -import java.util.Map; - -import entity.User; -import use_case.login.LoginUserDataAccessInterface; -import use_case.signup.SignupUserDataAccessInterface; - /** * The DAO for user data. */ -public class ChessDataAccessObject implements LoginUserDataAccessInterface, SignupUserDataAccessInterface { - - private final Map users = new HashMap<>(); - private String currentUser; - - @Override - public User get(String username) { - return users.get(username); - } - - @Override - public void setCurrentUser(String name) { - this.currentUser = name; - } - - @Override - public String getCurrentUser() { - return currentUser; - } - - @Override - public boolean existsByName(String username) { - return users.containsKey(username); - } - - @Override - public void save(User user) { - users.put(user.getName(), user); - } +public class ChessDataAccessObject { } From 1c55444e8f20cd29dc51ceafcb80a8fa0d37a2ec Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Mon, 25 Nov 2024 18:56:55 -0500 Subject: [PATCH 039/125] Views added for Signup, Login --- .../signup/SignupController.java | 36 ++++ .../signup/SignupPresenter.java | 50 +++++ .../interface_adapter/signup/SignupState.java | 71 +++++++ .../signup/SignupViewModel.java | 26 +++ src/main/java/view/LabelTextPanel.java | 15 ++ src/main/java/view/LoginView.java | 156 ++++++++++++++ src/main/java/view/SignupView.java | 197 ++++++++++++++++++ 7 files changed, 551 insertions(+) create mode 100644 src/main/java/interface_adapter/signup/SignupController.java create mode 100644 src/main/java/interface_adapter/signup/SignupPresenter.java create mode 100644 src/main/java/interface_adapter/signup/SignupState.java create mode 100644 src/main/java/interface_adapter/signup/SignupViewModel.java create mode 100644 src/main/java/view/LabelTextPanel.java create mode 100644 src/main/java/view/LoginView.java create mode 100644 src/main/java/view/SignupView.java diff --git a/src/main/java/interface_adapter/signup/SignupController.java b/src/main/java/interface_adapter/signup/SignupController.java new file mode 100644 index 000000000..c01d25aa5 --- /dev/null +++ b/src/main/java/interface_adapter/signup/SignupController.java @@ -0,0 +1,36 @@ +package interface_adapter.signup; + +import use_case.signup.SignupInputBoundary; +import use_case.signup.SignupInputData; + +/** + * Controller for the Signup Use Case. + */ +public class SignupController { + + private final SignupInputBoundary userSignupUseCaseInteractor; + + public SignupController(SignupInputBoundary userSignupUseCaseInteractor) { + this.userSignupUseCaseInteractor = userSignupUseCaseInteractor; + } + + /** + * Executes the Signup Use Case. + * @param username the username to sign up + * @param password1 the password + * @param password2 the password repeated + */ + public void execute(String username, String password1, String password2) { + final SignupInputData signupInputData = new SignupInputData( + username, password1, password2); + + userSignupUseCaseInteractor.execute(signupInputData); + } + + /** + * Executes the "switch to LoginView" Use Case. + */ + public void switchToLoginView() { + userSignupUseCaseInteractor.switchToLoginView(); + } +} diff --git a/src/main/java/interface_adapter/signup/SignupPresenter.java b/src/main/java/interface_adapter/signup/SignupPresenter.java new file mode 100644 index 000000000..9b654077e --- /dev/null +++ b/src/main/java/interface_adapter/signup/SignupPresenter.java @@ -0,0 +1,50 @@ +package interface_adapter.signup; + +import interface_adapter.ViewManagerModel; +import interface_adapter.login.LoginState; +import interface_adapter.login.LoginViewModel; +import use_case.signup.SignupOutputBoundary; +import use_case.signup.SignupOutputData; + +/** + * The Presenter for the Signup Use Case. + */ +public class SignupPresenter implements SignupOutputBoundary { + + private final SignupViewModel signupViewModel; + private final LoginViewModel loginViewModel; + private final ViewManagerModel viewManagerModel; + + public SignupPresenter(ViewManagerModel viewManagerModel, + SignupViewModel signupViewModel, + LoginViewModel loginViewModel) { + this.viewManagerModel = viewManagerModel; + this.signupViewModel = signupViewModel; + this.loginViewModel = loginViewModel; + } + + @Override + public void prepareSuccessView(SignupOutputData response) { + // On success, switch to the login view. + final LoginState loginState = loginViewModel.getState(); + loginState.setUsername(response.getUsername()); + this.loginViewModel.setState(loginState); + loginViewModel.firePropertyChanged(); + + viewManagerModel.setState(loginViewModel.getViewName()); + viewManagerModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String error) { + final SignupState signupState = signupViewModel.getState(); + signupState.setUsernameError(error); + signupViewModel.firePropertyChanged(); + } + + @Override + public void switchToLoginView() { + viewManagerModel.setState(loginViewModel.getViewName()); + viewManagerModel.firePropertyChanged(); + } +} diff --git a/src/main/java/interface_adapter/signup/SignupState.java b/src/main/java/interface_adapter/signup/SignupState.java new file mode 100644 index 000000000..82337802a --- /dev/null +++ b/src/main/java/interface_adapter/signup/SignupState.java @@ -0,0 +1,71 @@ +package interface_adapter.signup; + +/** + * The state for the Signup View Model. + */ +public class SignupState { + private String username = ""; + private String usernameError; + private String password = ""; + private String passwordError; + private String repeatPassword = ""; + private String repeatPasswordError; + + public String getUsername() { + return username; + } + + public String getUsernameError() { + return usernameError; + } + + public String getPassword() { + return password; + } + + public String getPasswordError() { + return passwordError; + } + + public String getRepeatPassword() { + return repeatPassword; + } + + public String getRepeatPasswordError() { + return repeatPasswordError; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setUsernameError(String usernameError) { + this.usernameError = usernameError; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setPasswordError(String passwordError) { + this.passwordError = passwordError; + } + + public void setRepeatPassword(String repeatPassword) { + this.repeatPassword = repeatPassword; + } + + public void setRepeatPasswordError(String repeatPasswordError) { + this.repeatPasswordError = repeatPasswordError; + } + + @Override + public String toString() { + return "SignupState{" + + "username='" + username + '\'' + + ", password='" + password + '\'' + + ", repeatPassword='" + repeatPassword + '\'' + + '}'; + } +} + diff --git a/src/main/java/interface_adapter/signup/SignupViewModel.java b/src/main/java/interface_adapter/signup/SignupViewModel.java new file mode 100644 index 000000000..29fe7b57c --- /dev/null +++ b/src/main/java/interface_adapter/signup/SignupViewModel.java @@ -0,0 +1,26 @@ +package interface_adapter.signup; + +import interface_adapter.ViewModel; + +/** + * The ViewModel for the Signup View. + */ +public class SignupViewModel extends ViewModel { + + public static final String TITLE_LABEL = "Sign Up View"; + public static final String USERNAME_LABEL = "Choose username"; + public static final String PASSWORD_LABEL = "Choose password"; + public static final String REPEAT_PASSWORD_LABEL = "Enter password again"; + + public static final String SIGNUP_BUTTON_LABEL = "Sign up"; + public static final String CANCEL_BUTTON_LABEL = "Cancel"; + + public static final String TO_LOGIN_BUTTON_LABEL = "Go to Login"; + + public SignupViewModel() { + super("sign up"); + setState(new SignupState()); + } + +} + diff --git a/src/main/java/view/LabelTextPanel.java b/src/main/java/view/LabelTextPanel.java new file mode 100644 index 000000000..e7138555f --- /dev/null +++ b/src/main/java/view/LabelTextPanel.java @@ -0,0 +1,15 @@ +package view; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; + +/** + * A panel containing a label and a text field. + */ +class LabelTextPanel extends JPanel { + LabelTextPanel(JLabel label, JTextField textField) { + this.add(label); + this.add(textField); + } +} diff --git a/src/main/java/view/LoginView.java b/src/main/java/view/LoginView.java new file mode 100644 index 000000000..68dea9ab5 --- /dev/null +++ b/src/main/java/view/LoginView.java @@ -0,0 +1,156 @@ +package view; + +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JPasswordField; +import javax.swing.JTextField; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +import interface_adapter.login.LoginController; +import interface_adapter.login.LoginState; +import interface_adapter.login.LoginViewModel; + +/** + * The View for when the user is logging into the program. + */ +public class LoginView extends JPanel implements ActionListener, PropertyChangeListener { + + private final String viewName = "log in"; + private final LoginViewModel loginViewModel; + + private final JTextField usernameInputField = new JTextField(15); + private final JLabel usernameErrorField = new JLabel(); + + private final JPasswordField passwordInputField = new JPasswordField(15); + private final JLabel passwordErrorField = new JLabel(); + + private final JButton logIn; + private final JButton cancel; + private final LoginController loginController; + + public LoginView(LoginViewModel loginViewModel, LoginController controller) { + + this.loginController = controller; + this.loginViewModel = loginViewModel; + this.loginViewModel.addPropertyChangeListener(this); + + final JLabel title = new JLabel("Login Screen"); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + + final LabelTextPanel usernameInfo = new LabelTextPanel( + new JLabel("Username"), usernameInputField); + final LabelTextPanel passwordInfo = new LabelTextPanel( + new JLabel("Password"), passwordInputField); + + final JPanel buttons = new JPanel(); + logIn = new JButton("log in"); + buttons.add(logIn); + cancel = new JButton("cancel"); + buttons.add(cancel); + + logIn.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(logIn)) { + final LoginState currentState = loginViewModel.getState(); + + loginController.execute( + currentState.getUsername(), + currentState.getPassword() + ); + } + } + } + ); + + cancel.addActionListener(this); + + usernameInputField.getDocument().addDocumentListener(new DocumentListener() { + + private void documentListenerHelper() { + final LoginState currentState = loginViewModel.getState(); + currentState.setUsername(usernameInputField.getText()); + loginViewModel.setState(currentState); + } + + @Override + public void insertUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + documentListenerHelper(); + } + }); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + passwordInputField.getDocument().addDocumentListener(new DocumentListener() { + + private void documentListenerHelper() { + final LoginState currentState = loginViewModel.getState(); + currentState.setPassword(new String(passwordInputField.getPassword())); + loginViewModel.setState(currentState); + } + + @Override + public void insertUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + documentListenerHelper(); + } + }); + + this.add(title); + this.add(usernameInfo); + this.add(usernameErrorField); + this.add(passwordInfo); + this.add(buttons); + } + + /** + * React to a button click that results in evt. + * @param evt the ActionEvent to react to + */ + public void actionPerformed(ActionEvent evt) { + System.out.println("Click " + evt.getActionCommand()); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + final LoginState state = (LoginState) evt.getNewValue(); + setFields(state); + usernameErrorField.setText(state.getLoginError()); + } + + private void setFields(LoginState state) { + usernameInputField.setText(state.getUsername()); + } + + public String getViewName() { + return viewName; + } +} diff --git a/src/main/java/view/SignupView.java b/src/main/java/view/SignupView.java new file mode 100644 index 000000000..ebe7f0761 --- /dev/null +++ b/src/main/java/view/SignupView.java @@ -0,0 +1,197 @@ +package view; + +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPasswordField; +import javax.swing.JTextField; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +import interface_adapter.signup.SignupController; +import interface_adapter.signup.SignupState; +import interface_adapter.signup.SignupViewModel; + +/** + * The View for the Signup Use Case. + */ +public class SignupView extends JPanel implements ActionListener, PropertyChangeListener { + private final String viewName = "sign up"; + + private final SignupViewModel signupViewModel; + private final JTextField usernameInputField = new JTextField(15); + private final JPasswordField passwordInputField = new JPasswordField(15); + private final JPasswordField repeatPasswordInputField = new JPasswordField(15); + private final SignupController signupController; + + private final JButton signUp; + private final JButton cancel; + private final JButton toLogin; + + public SignupView(SignupController controller, SignupViewModel signupViewModel) { + + this.signupController = controller; + this.signupViewModel = signupViewModel; + signupViewModel.addPropertyChangeListener(this); + + final JLabel title = new JLabel(SignupViewModel.TITLE_LABEL); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + + final LabelTextPanel usernameInfo = new LabelTextPanel( + new JLabel(SignupViewModel.USERNAME_LABEL), usernameInputField); + final LabelTextPanel passwordInfo = new LabelTextPanel( + new JLabel(SignupViewModel.PASSWORD_LABEL), passwordInputField); + final LabelTextPanel repeatPasswordInfo = new LabelTextPanel( + new JLabel(SignupViewModel.REPEAT_PASSWORD_LABEL), repeatPasswordInputField); + + final JPanel buttons = new JPanel(); + toLogin = new JButton(SignupViewModel.TO_LOGIN_BUTTON_LABEL); + buttons.add(toLogin); + signUp = new JButton(SignupViewModel.SIGNUP_BUTTON_LABEL); + buttons.add(signUp); + cancel = new JButton(SignupViewModel.CANCEL_BUTTON_LABEL); + buttons.add(cancel); + + signUp.addActionListener( + // This creates an anonymous subclass of ActionListener and instantiates it. + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(signUp)) { + final SignupState currentState = signupViewModel.getState(); + + signupController.execute( + currentState.getUsername(), + currentState.getPassword(), + currentState.getRepeatPassword() + ); + } + } + } + ); + + toLogin.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + signupController.switchToLoginView(); + } + } + ); + + cancel.addActionListener(this); + + addUsernameListener(); + addPasswordListener(); + addRepeatPasswordListener(); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + this.add(title); + this.add(usernameInfo); + this.add(passwordInfo); + this.add(repeatPasswordInfo); + this.add(buttons); + } + + private void addUsernameListener() { + usernameInputField.getDocument().addDocumentListener(new DocumentListener() { + + private void documentListenerHelper() { + final SignupState currentState = signupViewModel.getState(); + currentState.setUsername(usernameInputField.getText()); + signupViewModel.setState(currentState); + } + + @Override + public void insertUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + documentListenerHelper(); + } + }); + } + + private void addPasswordListener() { + passwordInputField.getDocument().addDocumentListener(new DocumentListener() { + + private void documentListenerHelper() { + final SignupState currentState = signupViewModel.getState(); + currentState.setPassword(new String(passwordInputField.getPassword())); + signupViewModel.setState(currentState); + } + + @Override + public void insertUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + documentListenerHelper(); + } + }); + } + + private void addRepeatPasswordListener() { + repeatPasswordInputField.getDocument().addDocumentListener(new DocumentListener() { + + private void documentListenerHelper() { + final SignupState currentState = signupViewModel.getState(); + currentState.setRepeatPassword(new String(repeatPasswordInputField.getPassword())); + signupViewModel.setState(currentState); + } + + @Override + public void insertUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + documentListenerHelper(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + documentListenerHelper(); + } + }); + } + + @Override + public void actionPerformed(ActionEvent evt) { + JOptionPane.showMessageDialog(this, "Cancel not implemented yet."); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + final SignupState state = (SignupState) evt.getNewValue(); + if (state.getUsernameError() != null) { + JOptionPane.showMessageDialog(this, state.getUsernameError()); + } + } + + public String getViewName() { + return viewName; + } +} From 9b84b615d5b3e1e320e747354d4de5cf491f84f7 Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Mon, 25 Nov 2024 19:24:46 -0500 Subject: [PATCH 040/125] Signup and Login App --- src/main/java/app/LoginApp.java | 58 ++++++++++++++++++++++++++++++++ src/main/java/app/SignupApp.java | 55 ++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 src/main/java/app/LoginApp.java create mode 100644 src/main/java/app/SignupApp.java diff --git a/src/main/java/app/LoginApp.java b/src/main/java/app/LoginApp.java new file mode 100644 index 000000000..67af2ad51 --- /dev/null +++ b/src/main/java/app/LoginApp.java @@ -0,0 +1,58 @@ +package app; + +import interface_adapter.ViewManagerModel; +import interface_adapter.logged_in.LoggedInViewModel; +import interface_adapter.login.LoginController; +import interface_adapter.login.LoginPresenter; +import interface_adapter.login.LoginViewModel; +import use_case.login.LoginInputBoundary; +import use_case.login.LoginInteractor; +import use_case.login.LoginOutputBoundary; +import use_case.login.LoginUserDataAccessInterface; +import view.LoginView; + +/** + * This class contains the static factory function for creating the LoginView. + */ +public final class LoginApp { + + /** Prevent instantiation. */ + private LoginApp() { + + } + + /** + * Factory function for creating the LoginView. + * @param viewManagerModel the ViewManagerModel to inject into the LoginView + * @param loginViewModel the LoginViewModel to inject into the LoginView + * @param loggedInViewModel the LoggedInViewModel to inject into the LoginView + * @param userDataAccessObject the LoginUserDataAccessInterface to inject into the LoginView + * @return the LoginView created for the provided input classes + */ + public static LoginView create( + ViewManagerModel viewManagerModel, + LoginViewModel loginViewModel, + LoggedInViewModel loggedInViewModel, + LoginUserDataAccessInterface userDataAccessObject) { + + final LoginController loginController = createLoginUseCase(viewManagerModel, loginViewModel, + loggedInViewModel, userDataAccessObject); + return new LoginView(loginViewModel, loginController); + + } + + private static LoginController createLoginUseCase( + ViewManagerModel viewManagerModel, + LoginViewModel loginViewModel, + LoggedInViewModel loggedInViewModel, + LoginUserDataAccessInterface userDataAccessObject) { + + // Notice how we pass this method's parameters to the Presenter. + final LoginOutputBoundary loginOutputBoundary = new LoginPresenter(viewManagerModel, + loggedInViewModel, loginViewModel); + final LoginInputBoundary loginInteractor = new LoginInteractor( + userDataAccessObject, loginOutputBoundary); + + return new LoginController(loginInteractor); + } +} diff --git a/src/main/java/app/SignupApp.java b/src/main/java/app/SignupApp.java new file mode 100644 index 000000000..b43fd290f --- /dev/null +++ b/src/main/java/app/SignupApp.java @@ -0,0 +1,55 @@ +package app; + +import interface_adapter.ViewManagerModel; +import interface_adapter.login.LoginViewModel; +import interface_adapter.signup.SignupController; +import interface_adapter.signup.SignupPresenter; +import interface_adapter.signup.SignupViewModel; +import use_case.signup.SignupInputBoundary; +import use_case.signup.SignupInteractor; +import use_case.signup.SignupOutputBoundary; +import use_case.signup.SignupUserDataAccessInterface; +import view.SignupView; + +/** + * This class contains the static factory function for creating the SignupView. + */ +public final class SignupApp { + + /** Prevent instantiation. */ + private SignupApp() { + + } + + /** + * Factory function for creating the SignupView. + * @param viewManagerModel the ViewManagerModel to inject into the SignupView + * @param loginViewModel the LoginViewModel to inject into the SignupView + * @param signupViewModel the SignupViewModel to inject into the SignupView + * @param userDataAccessObject the SignupUserDataAccessInterface to inject into the SignupView + * @return the LoginView created for the provided input classes + */ + public static SignupView create( + ViewManagerModel viewManagerModel, LoginViewModel loginViewModel, + SignupViewModel signupViewModel, SignupUserDataAccessInterface userDataAccessObject) { + + final SignupController signupController = createUserSignupUseCase(viewManagerModel, signupViewModel, + loginViewModel, userDataAccessObject); + return new SignupView(signupController, signupViewModel); + + } + + private static SignupController createUserSignupUseCase(ViewManagerModel viewManagerModel, + SignupViewModel signupViewModel, + LoginViewModel loginViewModel, + SignupUserDataAccessInterface userDataAccessObject) { + + final SignupOutputBoundary signupOutputBoundary = new SignupPresenter(viewManagerModel, + signupViewModel, loginViewModel); + + final SignupInputBoundary userSignupInteractor = new SignupInteractor( + userDataAccessObject, signupOutputBoundary); + + return new SignupController(userSignupInteractor); + } +} From 7a13af37c802abd735204f8c3618190cc0fe1f69 Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Wed, 27 Nov 2024 02:35:08 -0500 Subject: [PATCH 041/125] Making the Signup, Login view work together with Chess Game --- src/main/java/app/CK_ChessAppBuilder.java | 63 +++++++++++++ src/main/java/app/Main_ck.java | 65 +++++++++++++ .../logged_in/LoggedInPresenter.java | 2 +- .../logged_in/LoggedInState.java | 14 ++- .../logged_in/LoggedInViewModel.java | 4 + src/main/java/view/LoggedInView.java | 94 +++++++++++++++++++ src/main/java/view/SignupView.java | 1 - 7 files changed, 239 insertions(+), 4 deletions(-) create mode 100644 src/main/java/app/CK_ChessAppBuilder.java create mode 100644 src/main/java/app/Main_ck.java create mode 100644 src/main/java/view/LoggedInView.java diff --git a/src/main/java/app/CK_ChessAppBuilder.java b/src/main/java/app/CK_ChessAppBuilder.java new file mode 100644 index 000000000..eea64bdf6 --- /dev/null +++ b/src/main/java/app/CK_ChessAppBuilder.java @@ -0,0 +1,63 @@ +package app; + +import data_access.ChessDataAccessObject; +import interface_adapter.ViewManagerModel; +import interface_adapter.move.MoveController; +import interface_adapter.move.MovePresenter; +import interface_adapter.move.MoveViewModel; +import use_case.move.MoveInteractor; +import use_case.move.MoveOutPutBoundary; +import view.ChessBoardView; + +/** + * Builder for the Note Application. + */ +public class CK_ChessAppBuilder { + public static final int HEIGHT = 800; + public static final int WIDTH = 800; + // TODO change to ChessDataAccessInterface once implemented + private ChessDataAccessObject chessDataAccessObject; + private MoveViewModel moveViewModel = new MoveViewModel(); + private final ViewManagerModel viewManagerModel = new ViewManagerModel(); + private ChessBoardView chessBoardView; + private MoveInteractor moveInteractor; + + /** + * Set the ChessDAO to be used in this application. + * @param chessDataAccess the DAO to use + * @return this builder + */ + public CK_ChessAppBuilder addChessDAO(ChessDataAccessObject chessDataAccess) { + chessDataAccessObject = chessDataAccess; + return this; + } + + /** + * Creates the objects for the Move Use Case and connects the ChessBoardView to Move controller. + * @return this builder + */ + public CK_ChessAppBuilder addMoveUseCase() { + final MoveOutPutBoundary moveOutPutBoundary = new MovePresenter(moveViewModel, viewManagerModel); + moveInteractor = new MoveInteractor( + chessDataAccessObject, moveOutPutBoundary); + + final MoveController moveController = new MoveController(moveInteractor); + chessBoardView.setMoveController(moveController); + return this; + } + + /** + * Creates the ChessBoardView and underlying MoveViewModel. + * @return this builder + */ + public CK_ChessAppBuilder addMoveView() { + moveViewModel = new MoveViewModel(); + final MoveController moveController = new MoveController(moveInteractor); + chessBoardView = new ChessBoardView(moveViewModel, moveController); + return this; + } + + public ChessBoardView buildChessBoardView() { + return chessBoardView; + } +} diff --git a/src/main/java/app/Main_ck.java b/src/main/java/app/Main_ck.java new file mode 100644 index 000000000..48d5ebaa9 --- /dev/null +++ b/src/main/java/app/Main_ck.java @@ -0,0 +1,65 @@ +package app; + +import java.awt.CardLayout; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.WindowConstants; + +import data_access.ChessDataAccessObject; +import data_access.UserDataAccessObject; +import interface_adapter.ViewManagerModel; +import interface_adapter.logged_in.LoggedInViewModel; +import interface_adapter.login.LoginViewModel; +import interface_adapter.signup.SignupViewModel; +import view.*; + +/** + * Main that activates login page. + */ +public class Main_ck { + + /** + * The main method for starting the program with an external database used to persist user data. + * @param args input to main + */ + public static void main(String[] args) { + + final JFrame frame = new JFrame("Chess Game Login"); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + + final CardLayout cardLayout = new CardLayout(); + final JPanel views = new JPanel(cardLayout); + frame.add(views); + + final ViewManagerModel viewManagerModel = new ViewManagerModel(); + final ViewManager viewManager = new ViewManager(views, cardLayout, viewManagerModel); + + final LoginViewModel loginViewModel = new LoginViewModel(); + final LoggedInViewModel loggedInViewModel = new LoggedInViewModel(); + final SignupViewModel signupViewModel = new SignupViewModel(); + + final UserDataAccessObject userDataAccessObject = new UserDataAccessObject(); + final SignupView signupView = SignupApp.create(viewManagerModel, loginViewModel, signupViewModel, userDataAccessObject); + final LoginView loginView = LoginApp.create(viewManagerModel, loginViewModel, loggedInViewModel, userDataAccessObject); + final LoggedInView loggedInView = new LoggedInView(viewManagerModel, loggedInViewModel); + + views.add(signupView, signupView.getViewName()); + views.add(loginView, loginView.getViewName()); + views.add(loggedInView, loggedInView.getViewName()); + + final CK_ChessAppBuilder chessAppBuilder = new CK_ChessAppBuilder(); + chessAppBuilder.addChessDAO(new ChessDataAccessObject()) + .addMoveView() + .addMoveUseCase(); + + final ChessBoardView chessBoardView = chessAppBuilder.buildChessBoardView(); + views.add(chessBoardView, "chessBoardView"); + + viewManagerModel.setState(signupView.getViewName()); + viewManagerModel.firePropertyChanged(); + + frame.pack(); + frame.setVisible(true); + } +} diff --git a/src/main/java/interface_adapter/logged_in/LoggedInPresenter.java b/src/main/java/interface_adapter/logged_in/LoggedInPresenter.java index 568f9b209..8e91fd80d 100644 --- a/src/main/java/interface_adapter/logged_in/LoggedInPresenter.java +++ b/src/main/java/interface_adapter/logged_in/LoggedInPresenter.java @@ -16,7 +16,7 @@ public LoggedInPresenter(ViewManagerModel viewManagerModel, this.loggedInViewModel = loggedInViewModel; } - public void prepareLoggedInView(String username) { + public void prepareSuccessView(String username) { final LoggedInState state = loggedInViewModel.getState(); state.setUsername(username); loggedInViewModel.setState(state); diff --git a/src/main/java/interface_adapter/logged_in/LoggedInState.java b/src/main/java/interface_adapter/logged_in/LoggedInState.java index 22e0209f5..4f7fca6ed 100644 --- a/src/main/java/interface_adapter/logged_in/LoggedInState.java +++ b/src/main/java/interface_adapter/logged_in/LoggedInState.java @@ -5,9 +5,11 @@ */ public class LoggedInState { private String username = ""; + private String password = ""; public LoggedInState(LoggedInState copy) { username = copy.username; + password = copy.password; } // Because of the previous copy constructor, the default constructor must be explicit. @@ -15,12 +17,20 @@ public LoggedInState() { } + public void setUsername(String username) { + this.username = username; + } + + public void setPassword(String password) { + this.password = password; + } + public String getUsername() { return username; } - public void setUsername(String username) { - this.username = username; + public String getPassword() { + return password; } } diff --git a/src/main/java/interface_adapter/logged_in/LoggedInViewModel.java b/src/main/java/interface_adapter/logged_in/LoggedInViewModel.java index ba0184f58..6398183cc 100644 --- a/src/main/java/interface_adapter/logged_in/LoggedInViewModel.java +++ b/src/main/java/interface_adapter/logged_in/LoggedInViewModel.java @@ -12,4 +12,8 @@ public LoggedInViewModel() { setState(new LoggedInState()); } + public String getUsername() { + return getState().getUsername(); + } + } diff --git a/src/main/java/view/LoggedInView.java b/src/main/java/view/LoggedInView.java new file mode 100644 index 000000000..4e4d9711b --- /dev/null +++ b/src/main/java/view/LoggedInView.java @@ -0,0 +1,94 @@ +package view; + +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; + +import interface_adapter.logged_in.LoggedInState; +import interface_adapter.logged_in.LoggedInViewModel; +import interface_adapter.ViewManagerModel; + +/** + * The View for when the user is logged into the program. + */ +public class LoggedInView extends JPanel implements ActionListener, PropertyChangeListener { + + private final String viewName = "logged in"; + private final LoggedInViewModel loggedInViewModel; + private final JLabel passwordErrorField = new JLabel(); + + private final JLabel username; + + private final JButton logOut; + + private final JTextField passwordInputField = new JTextField(15); + private final JButton startChess; + + public LoggedInView(ViewManagerModel viewManagerModel, LoggedInViewModel loggedInViewModel) { + this.loggedInViewModel = loggedInViewModel; + this.loggedInViewModel.addPropertyChangeListener(this); + + final JLabel title = new JLabel("Logged In Screen"); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + + final LabelTextPanel passwordInfo = new LabelTextPanel( + new JLabel("Password"), passwordInputField); + + final JLabel usernameInfo = new JLabel("Currently logged in: "); + username = new JLabel(); + + final JPanel buttons = new JPanel(); + logOut = new JButton("Log Out"); + buttons.add(logOut); + + startChess = new JButton("Start Chess Game"); + buttons.add(startChess); + + logOut.addActionListener(this); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + startChess.addActionListener( + evt -> { + if (evt.getSource().equals(startChess)) { + viewManagerModel.setState("chessBoardView"); + viewManagerModel.firePropertyChanged(); + } + } + ); + + this.add(title); + this.add(usernameInfo); + this.add(username); + + this.add(passwordInfo); + this.add(passwordErrorField); + this.add(buttons); + } + + /** + * React to a button click that results in evt. + * @param evt the ActionEvent to react to + */ + public void actionPerformed(ActionEvent evt) { + System.out.println("Click " + evt.getActionCommand()); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + final LoggedInState state = (LoggedInState) evt.getNewValue(); + username.setText(state.getUsername()); + } + + public String getViewName() { + return viewName; + } +} diff --git a/src/main/java/view/SignupView.java b/src/main/java/view/SignupView.java index ebe7f0761..3ca258278 100644 --- a/src/main/java/view/SignupView.java +++ b/src/main/java/view/SignupView.java @@ -61,7 +61,6 @@ public SignupView(SignupController controller, SignupViewModel signupViewModel) buttons.add(cancel); signUp.addActionListener( - // This creates an anonymous subclass of ActionListener and instantiates it. new ActionListener() { public void actionPerformed(ActionEvent evt) { if (evt.getSource().equals(signUp)) { From c275bd5d1bcff4e0450165935e9a692dacdf3b96 Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Wed, 27 Nov 2024 15:42:40 -0500 Subject: [PATCH 042/125] 'ChessBoardView.java' can now highlight 'Valid' grid of 'MoveViewModel.java' --- .../java/interface_adapter/move/MoveViewModel.java | 6 +++--- src/main/java/view/ChessBoardView.java | 10 ++++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main/java/interface_adapter/move/MoveViewModel.java b/src/main/java/interface_adapter/move/MoveViewModel.java index ef52c3711..4cdb522fe 100644 --- a/src/main/java/interface_adapter/move/MoveViewModel.java +++ b/src/main/java/interface_adapter/move/MoveViewModel.java @@ -10,9 +10,9 @@ public class MoveViewModel extends ViewModel { public static final String TITLE_LABEL = "Move View"; private final String[][] pieces = { - {"♖", "♘", "♗", "♕", "♔", "♗", "♘", "♖"}, // Black major pieces - {"♙", "♙", "♙", "♙", "♙", "♙", "♙", "♙"}, // Black pawns - {null, null, null, null, null, null, null, null}, // Empty row + {"♜", "♞", "♝", "♛", "♚", "♝", "♞", "♜"}, // Black major pieces + {"♟", "♟", "♟", "♟", "♟", "♟", "♟", "♟"}, // Black pawns + {null, null, null, null, null, null, null, "Valid"}, // Empty row with one Valid move {null, null, null, null, null, null, null, null}, // Empty row {null, null, null, null, null, null, null, null}, // Empty row {null, null, null, null, null, null, null, null}, // Empty row diff --git a/src/main/java/view/ChessBoardView.java b/src/main/java/view/ChessBoardView.java index d3246b346..8f70257a9 100644 --- a/src/main/java/view/ChessBoardView.java +++ b/src/main/java/view/ChessBoardView.java @@ -55,8 +55,14 @@ public ChessBoardView(MoveViewModel moveViewModel, MoveController moveController // Add pieces to the board final String[][] pieces = moveViewModel.getPieces(); if (pieces[row][col] != null) { - button.setText(pieces[row][col]); - button.setFont(new Font("Serif", Font.BOLD, fontSize)); + // Set highlighted background color associate with valid moves. + if (pieces[row][col].equals("Valid")) { + button.setBackground(Color.YELLOW); + } + else { + button.setText(pieces[row][col]); + button.setFont(new Font("Serif", Font.BOLD, fontSize)); + } } button.setFocusPainted(true); From 96403128b967d4bde0e2329387c728167d20328b Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Wed, 27 Nov 2024 15:42:40 -0500 Subject: [PATCH 043/125] 'ChessBoardView.java' can now highlight 'Valid' grid of 'MoveViewModel.java' --- .../java/interface_adapter/move/MoveViewModel.java | 6 +++--- src/main/java/view/ChessBoardView.java | 10 ++++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main/java/interface_adapter/move/MoveViewModel.java b/src/main/java/interface_adapter/move/MoveViewModel.java index ef52c3711..4cdb522fe 100644 --- a/src/main/java/interface_adapter/move/MoveViewModel.java +++ b/src/main/java/interface_adapter/move/MoveViewModel.java @@ -10,9 +10,9 @@ public class MoveViewModel extends ViewModel { public static final String TITLE_LABEL = "Move View"; private final String[][] pieces = { - {"♖", "♘", "♗", "♕", "♔", "♗", "♘", "♖"}, // Black major pieces - {"♙", "♙", "♙", "♙", "♙", "♙", "♙", "♙"}, // Black pawns - {null, null, null, null, null, null, null, null}, // Empty row + {"♜", "♞", "♝", "♛", "♚", "♝", "♞", "♜"}, // Black major pieces + {"♟", "♟", "♟", "♟", "♟", "♟", "♟", "♟"}, // Black pawns + {null, null, null, null, null, null, null, "Valid"}, // Empty row with one Valid move {null, null, null, null, null, null, null, null}, // Empty row {null, null, null, null, null, null, null, null}, // Empty row {null, null, null, null, null, null, null, null}, // Empty row diff --git a/src/main/java/view/ChessBoardView.java b/src/main/java/view/ChessBoardView.java index d3246b346..8f70257a9 100644 --- a/src/main/java/view/ChessBoardView.java +++ b/src/main/java/view/ChessBoardView.java @@ -55,8 +55,14 @@ public ChessBoardView(MoveViewModel moveViewModel, MoveController moveController // Add pieces to the board final String[][] pieces = moveViewModel.getPieces(); if (pieces[row][col] != null) { - button.setText(pieces[row][col]); - button.setFont(new Font("Serif", Font.BOLD, fontSize)); + // Set highlighted background color associate with valid moves. + if (pieces[row][col].equals("Valid")) { + button.setBackground(Color.YELLOW); + } + else { + button.setText(pieces[row][col]); + button.setFont(new Font("Serif", Font.BOLD, fontSize)); + } } button.setFocusPainted(true); From b012a2ec94058478ef912dc018bade498e538315 Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Thu, 28 Nov 2024 10:22:37 -0500 Subject: [PATCH 044/125] 'showProfile' button added into 'LoggedInView.java' for 'showProfile' use case --- src/main/java/view/LoggedInView.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/view/LoggedInView.java b/src/main/java/view/LoggedInView.java index 4e4d9711b..0845f6269 100644 --- a/src/main/java/view/LoggedInView.java +++ b/src/main/java/view/LoggedInView.java @@ -31,6 +31,7 @@ public class LoggedInView extends JPanel implements ActionListener, PropertyChan private final JTextField passwordInputField = new JTextField(15); private final JButton startChess; + private final JButton showProfile; public LoggedInView(ViewManagerModel viewManagerModel, LoggedInViewModel loggedInViewModel) { this.loggedInViewModel = loggedInViewModel; @@ -49,8 +50,11 @@ public LoggedInView(ViewManagerModel viewManagerModel, LoggedInViewModel loggedI logOut = new JButton("Log Out"); buttons.add(logOut); + showProfile = new JButton("Show Profile"); + startChess = new JButton("Start Chess Game"); buttons.add(startChess); + buttons.add(showProfile); logOut.addActionListener(this); From dfdba7557a8a8ef5cb6056d71c4a2de9eb9b45dc Mon Sep 17 00:00:00 2001 From: J0hnDing Date: Thu, 28 Nov 2024 17:02:27 -0500 Subject: [PATCH 045/125] 1. Change the data type of position from Arraylist to int[]. 2. Implemented most of the MoveInteractor, OutputBoundary and data. 3. Added a few more pieces --- src/main/java/app/ChessAppBuilder.java | 4 +- src/main/java/entity/Bishop.java | 49 ++++++++++++++ src/main/java/entity/Board.java | 23 ++++--- src/main/java/entity/ChessPiece.java | 17 +++-- src/main/java/entity/Game.java | 31 ++++++++- src/main/java/entity/Pawn.java | 23 +++++++ src/main/java/entity/Queen.java | 25 +++++++ src/main/java/entity/Rook.java | 19 ++++-- .../move/MoveController.java | 9 ++- .../interface_adapter/move/MovePresenter.java | 16 ++++- .../java/use_case/move/MoveInputdata.java | 12 ++-- .../java/use_case/move/MoveInteractor.java | 67 +++++++++++++++++-- .../use_case/move/MoveOutPutBoundary.java | 4 -- .../java/use_case/move/MoveOutputdata.java | 19 ++++++ src/test/java/view/ChessBoardViewTest.java | 6 +- 15 files changed, 274 insertions(+), 50 deletions(-) create mode 100644 src/main/java/entity/Bishop.java create mode 100644 src/main/java/entity/Pawn.java create mode 100644 src/main/java/entity/Queen.java delete mode 100644 src/main/java/use_case/move/MoveOutPutBoundary.java diff --git a/src/main/java/app/ChessAppBuilder.java b/src/main/java/app/ChessAppBuilder.java index d19f086c6..42dfd6085 100644 --- a/src/main/java/app/ChessAppBuilder.java +++ b/src/main/java/app/ChessAppBuilder.java @@ -9,7 +9,7 @@ import interface_adapter.move.MovePresenter; import interface_adapter.move.MoveViewModel; import use_case.move.MoveInteractor; -import use_case.move.MoveOutPutBoundary; +import use_case.move.MoveOutputBoundary; import view.ChessBoardView; /** @@ -40,7 +40,7 @@ public ChessAppBuilder addChessDAO(ChessDataAccessObject chessDataAccess) { * @return this builder */ public ChessAppBuilder addMoveUseCase() { - final MoveOutPutBoundary moveOutPutBoundary = new MovePresenter(moveViewModel, viewManagerModel); + final MoveOutputBoundary moveOutPutBoundary = new MovePresenter(moveViewModel, viewManagerModel); moveInteractor = new MoveInteractor( chessDataAccessObject, moveOutPutBoundary); diff --git a/src/main/java/entity/Bishop.java b/src/main/java/entity/Bishop.java new file mode 100644 index 000000000..548429c93 --- /dev/null +++ b/src/main/java/entity/Bishop.java @@ -0,0 +1,49 @@ +package entity; + +import java.util.ArrayList; + +public class Bishop extends ChessPiece { + public Bishop(String color, int x, int y) { + super(color, x, y); + } + + /** + * Returns all possible moves for a bishop from the given position on an 8x8 chessboard. + * + * @return A list of int arrays, each representing a valid move [newX, newY]. + */ + public ArrayList getValidMoves() { + final ArrayList validMoves = new ArrayList<>(); + final int x = this.getPosition()[0]; + final int y = this.getPosition()[1]; + // Up-Left Diagonal + int i = 1; + while (x - i >= 0 && y - i >= 0) { + validMoves.add(new int[]{x - i, y - i}); + i++; + } + + // Up-Right Diagonal + i = 1; + while (x + i < 8 && y - i >= 0) { + validMoves.add(new int[]{x + i, y - i}); + i++; + } + + // Down-Left Diagonal + i = 1; + while (x - i >= 0 && y + i < 8) { + validMoves.add(new int[]{x - i, y + i}); + i++; + } + + // Down-Right Diagonal + i = 1; + while (x + i < 8 && y + i < 8) { + validMoves.add(new int[]{x + i, y + i}); + i++; + } + + return validMoves; + } +} diff --git a/src/main/java/entity/Board.java b/src/main/java/entity/Board.java index 6264e1e98..d41279bb5 100644 --- a/src/main/java/entity/Board.java +++ b/src/main/java/entity/Board.java @@ -18,22 +18,29 @@ public Board(JSONObject boardFile) { /** * Returns if a tile is empty. - * @param col Column of tile - * @param row Row of tile + * @param position position of piece * @return bool */ - public boolean isEmpty(int col, int row) { - return grid[col][row] == null; + public boolean isEmpty(int[] position) { + return grid[position[1]][position[0]] == null; } /** * Returns the chess piece at a given tile. - * @param col Column of tile - * @param row Row of tile + * @param position position of piece * @return Chesspiece */ - public ChessPiece getPiece(int col, int row) { - return grid[col][row]; + public ChessPiece getPiece(int[] position) { + return grid[position[1]][position[0]]; + } + + public void clear(int[] position) { + grid[position[1]][position[0]] = null; + } + + public void moveToLocation(int[] position, ChessPiece piece) { + clear(piece.getPosition()); + grid[position[1]][position[0]] = piece; } } diff --git a/src/main/java/entity/ChessPiece.java b/src/main/java/entity/ChessPiece.java index 73dbea9d2..9291695e3 100644 --- a/src/main/java/entity/ChessPiece.java +++ b/src/main/java/entity/ChessPiece.java @@ -1,27 +1,30 @@ package entity; import java.util.ArrayList; - /** * The abstract class of all chess piece. */ public abstract class ChessPiece { - private String color; - private ArrayList position; + private final String color; + private int[] position; public ChessPiece(String color, int x, int y) { this.color = color; - position.add(x); - position.add(y); + this.position = new int[2]; + position[0] = x; + position[1] = y; } - public abstract ArrayList getValidMoves(Board board); + /** + * The abstract class for getting the valid moves of a piece. + */ + public abstract ArrayList getValidMoves(); public String getColor() { return color; } - public ArrayList getPosition() { + public int[] getPosition() { return this.position; } } diff --git a/src/main/java/entity/Game.java b/src/main/java/entity/Game.java index ecf9aa215..08ce24135 100644 --- a/src/main/java/entity/Game.java +++ b/src/main/java/entity/Game.java @@ -1,8 +1,8 @@ package entity; public class Game { - private Board board; - private String currentPlayer; + private final Board board; + private final String currentPlayer; private boolean gameOver; private boolean whiteTurn; //if whiteturn is false, then its blacks turn private boolean selectMode; //if select mode is false, game is in movemode. @@ -34,4 +34,31 @@ public String getCurrentPlayer() { return currentPlayer; } } + + public ChessPiece getChesspiece_to_move() { + return chesspiece_to_move; + } + + public void setChesspiece_to_move(ChessPiece chesspiece_to_move) { + this.chesspiece_to_move = chesspiece_to_move; + } + + public void switchMode() { + if (selectMode) { + selectMode = false; + } + else { + selectMode = true; + } + } + + public boolean getGameMode() { + return selectMode; + } + + public Board getBoard() { + return board; + } + + } diff --git a/src/main/java/entity/Pawn.java b/src/main/java/entity/Pawn.java new file mode 100644 index 000000000..5171bf20a --- /dev/null +++ b/src/main/java/entity/Pawn.java @@ -0,0 +1,23 @@ +package entity; + +import java.util.ArrayList; + +public class Pawn extends ChessPiece { + public Pawn(String color, int x, int y) { + super(color, x, y); + } + + /** + * Returns all possible moves for a pawn from the given position on an 8x8 chessboard. + * @return A list of int arrays, each representing a valid move [newX, newY]. + */ + public ArrayList getValidMoves() { + final ArrayList validMoves = new ArrayList<>(); + final int x = this.getPosition()[0]; + final int y = this.getPosition()[1]; + + //still to be implemented... + + return validMoves; + } +} diff --git a/src/main/java/entity/Queen.java b/src/main/java/entity/Queen.java new file mode 100644 index 000000000..42949203b --- /dev/null +++ b/src/main/java/entity/Queen.java @@ -0,0 +1,25 @@ +package entity; + +import java.util.ArrayList; + +public class Queen extends ChessPiece { + public Queen(String color, int x, int y) { + super(color, x, y); + } + + /** + * Returns all possible moves for a bishop from the given position on an 8x8 chessboard. + * + * @param position the position of the current piece + * @return A list of int arrays, each representing a valid move [newX, newY]. + */ + public ArrayList getValidMoves() { + final ArrayList validMoves = new ArrayList<>(); + final int x = this.getPosition()[0]; + final int y = this.getPosition()[1]; + + //yet to be implemented + + return validMoves; + } +} \ No newline at end of file diff --git a/src/main/java/entity/Rook.java b/src/main/java/entity/Rook.java index 4ce0261cd..a51e6dc04 100644 --- a/src/main/java/entity/Rook.java +++ b/src/main/java/entity/Rook.java @@ -2,17 +2,24 @@ import java.util.ArrayList; +/** + * The class that defines the rook piece. + */ public class Rook extends ChessPiece { public Rook(String color, int x, int y) { super(color, x, y); } + /** + * Return valid moves. + */ - public ArrayList getValidMoves(Board board) { - final ArrayList validMoves = new ArrayList<>(); - final int x = this.getPosition().get(0); - final int y = this.getPosition().get(1); + public ArrayList getValidMoves() { - for (int i = y - 1; i >= 02; i--) { + ArrayList validMoves = new ArrayList<>(); + final int x = this.getPosition()[0]; + final int y = this.getPosition()[1]; + + for (int i = y - 1; i >= 0; i--) { validMoves.add(new int[] {x, i}); // Move upwards in the column } for (int i = y + 1; i < 8; i++) { @@ -27,4 +34,4 @@ public ArrayList getValidMoves(Board board) { } return validMoves; } -} \ No newline at end of file +} diff --git a/src/main/java/interface_adapter/move/MoveController.java b/src/main/java/interface_adapter/move/MoveController.java index 6a74f5ccd..a9f7ca5cf 100644 --- a/src/main/java/interface_adapter/move/MoveController.java +++ b/src/main/java/interface_adapter/move/MoveController.java @@ -1,13 +1,12 @@ package interface_adapter.move; -import java.util.ArrayList; import use_case.move.MoveInputBoundary; import use_case.move.MoveInputdata; - /** * The controller for the Move Use Case. */ + public class MoveController { private final MoveInputBoundary moveInteractor; @@ -21,9 +20,9 @@ public MoveController(MoveInputBoundary moveInteractor) { * @param ycord the horizontal coordinate form 0 to 7 */ public void onClick(Integer xcord, Integer ycord) { - final ArrayList position = new ArrayList<>(); - position.add(xcord); - position.add(ycord); + final int[] position = new int[2]; + position[0] = xcord; + position[1] = ycord; final MoveInputdata moveInputdata = new MoveInputdata(position); moveInteractor.execute(moveInputdata); } diff --git a/src/main/java/interface_adapter/move/MovePresenter.java b/src/main/java/interface_adapter/move/MovePresenter.java index f4d5666bc..9f51108b9 100644 --- a/src/main/java/interface_adapter/move/MovePresenter.java +++ b/src/main/java/interface_adapter/move/MovePresenter.java @@ -1,12 +1,15 @@ package interface_adapter.move; +import chariot.model.MoveInfo; import interface_adapter.ViewManagerModel; -import use_case.move.MoveOutPutBoundary; +import use_case.move.MoveInputdata; +import use_case.move.MoveOutputBoundary; +import use_case.move.MoveOutputdata; /** * The presenter for Move use case. */ -public class MovePresenter implements MoveOutPutBoundary { +public class MovePresenter implements MoveOutputBoundary { private final MoveViewModel moveViewModel; private final ViewManagerModel viewManagerModel; @@ -14,4 +17,13 @@ public MovePresenter(MoveViewModel moveViewModel, ViewManagerModel viewManagerMo this.moveViewModel = moveViewModel; this.viewManagerModel = viewManagerModel; } + + public void prepareMove(MoveOutputdata input) { + // present the moved chess board + } + + public void prepareSelect(MoveOutputdata input) { + // present the select chess board + } + } diff --git a/src/main/java/use_case/move/MoveInputdata.java b/src/main/java/use_case/move/MoveInputdata.java index 6e9759c23..7a4bd4dde 100644 --- a/src/main/java/use_case/move/MoveInputdata.java +++ b/src/main/java/use_case/move/MoveInputdata.java @@ -1,14 +1,18 @@ package use_case.move; - -import java.util.ArrayList; +import entity.Game; /** * Input data for move use case. */ public class MoveInputdata { - private ArrayList position; + private final int[] position; - public MoveInputdata(ArrayList input) { + public MoveInputdata(int[] input) { this.position = input; } + + public int[] getPosition() { + return position; + } } + diff --git a/src/main/java/use_case/move/MoveInteractor.java b/src/main/java/use_case/move/MoveInteractor.java index bbf96feed..a79229b97 100644 --- a/src/main/java/use_case/move/MoveInteractor.java +++ b/src/main/java/use_case/move/MoveInteractor.java @@ -1,26 +1,81 @@ package use_case.move; +import java.util.ArrayList; + +import entity.ChessPiece; import entity.Game; + + /** * Move interactor who handles the business logic of move. */ public class MoveInteractor implements MoveInputBoundary { private final MoveDataAccessInterface moveDataAccessObject; - private final MoveOutPutBoundary moveOutPutBoundary; + private final MoveOutputBoundary moveOutPutBoundary; + private final Game game; public MoveInteractor(MoveDataAccessInterface moveDataAccessObject, - MoveOutPutBoundary moveOutPutBoundary) { + MoveOutputBoundary moveOutPutBoundary, + Game game) { this.moveDataAccessObject = moveDataAccessObject; this.moveOutPutBoundary = moveOutPutBoundary; + this.game = game; } -// private boolean isvalidmove() { -// // check if this move is valid -// } + /** + * Return a list of valid moves based on the chess game. + * @param chessPiece the piece + */ + private ArrayList validmoves(ChessPiece chessPiece) { + ArrayList full_list; + full_list = chessPiece.getValidMoves(); + //reduce full_list to a limited list based on the game, still to be implented + return full_list; + } @Override public void execute(MoveInputdata position) { - // Starting point of this class + final int[] pos = position.getPosition(); + if (game.getGameMode()) { + select(pos); + } + else { + move(pos); + } + + } + + /** + * Executes the usecase when a piece is selected. + * @param position the position of the selected piece. + */ + private void select(int[] position) { + final ChessPiece piece = game.getBoard().getPiece(position); + if (piece == null) { + //Nothing happends since no piece selected + final MoveOutputdata nulldata = new MoveOutputdata(new ArrayList<>(), game.getBoard()); + moveOutPutBoundary.prepareMove(nulldata); + } + else { + game.setChesspiece_to_move(piece); + game.switchMode(); + final MoveOutputdata selectdata = new MoveOutputdata(validmoves(piece), game.getBoard()); + moveOutPutBoundary.prepareSelect(selectdata); + } + } + + private void move(int[] pos) { + final ArrayList validmoves = validmoves(game.getChesspiece_to_move()); + if (validmoves.contains(pos)) { + game.getBoard().moveToLocation(pos, game.getChesspiece_to_move()); //Move the chess piece to location + final MoveOutputdata movedata = new MoveOutputdata(new ArrayList<>(), game.getBoard()); + moveOutPutBoundary.prepareMove(movedata); + } + else { + // Do Nothing since nothing happend + final MoveOutputdata nulldata = new MoveOutputdata(new ArrayList<>(), game.getBoard()); + moveOutPutBoundary.prepareMove(nulldata); + } } } diff --git a/src/main/java/use_case/move/MoveOutPutBoundary.java b/src/main/java/use_case/move/MoveOutPutBoundary.java deleted file mode 100644 index 96c066ce1..000000000 --- a/src/main/java/use_case/move/MoveOutPutBoundary.java +++ /dev/null @@ -1,4 +0,0 @@ -package use_case.move; - -public interface MoveOutPutBoundary { -} diff --git a/src/main/java/use_case/move/MoveOutputdata.java b/src/main/java/use_case/move/MoveOutputdata.java index 91cee2112..c0bd00423 100644 --- a/src/main/java/use_case/move/MoveOutputdata.java +++ b/src/main/java/use_case/move/MoveOutputdata.java @@ -1,4 +1,23 @@ package use_case.move; +import entity.Board; + +import java.util.ArrayList; + public class MoveOutputdata { + private final ArrayList validMoves; + private final Board board; //This is yet to be changed. + + public MoveOutputdata(ArrayList validMoves, Board board) { + this.validMoves = validMoves; + this.board = board; + } + + public ArrayList getValidMoves() { + return validMoves; + } + + public Board getBoard() { + return board; + } } diff --git a/src/test/java/view/ChessBoardViewTest.java b/src/test/java/view/ChessBoardViewTest.java index b12f03838..b100b4a9c 100644 --- a/src/test/java/view/ChessBoardViewTest.java +++ b/src/test/java/view/ChessBoardViewTest.java @@ -1,15 +1,13 @@ package view; import data_access.ChessDataAccessObject; -import entity.Board; -import entity.Game; import interface_adapter.ViewManagerModel; import interface_adapter.move.MoveController; import interface_adapter.move.MovePresenter; import interface_adapter.move.MoveViewModel; import use_case.move.MoveDataAccessInterface; import use_case.move.MoveInteractor; -import use_case.move.MoveOutPutBoundary; +import use_case.move.MoveOutputBoundary; import javax.swing.*; @@ -25,7 +23,7 @@ public static void main(String[] args) { MoveDataAccessInterface moveDataAccessObject = new ChessDataAccessObject(); MoveViewModel moveViewModel = new MoveViewModel(); ViewManagerModel viewManagerModel = new ViewManagerModel(); - MoveOutPutBoundary movePresenter = new MovePresenter(moveViewModel, viewManagerModel); + MoveOutputBoundary movePresenter = new MovePresenter(moveViewModel, viewManagerModel); MoveInteractor TestInteractor = new MoveInteractor(moveDataAccessObject, movePresenter); MoveController TestController = new MoveController(TestInteractor); From ac747c5babbf1843a9b36d66acc1e964868e73a9 Mon Sep 17 00:00:00 2001 From: J0hnDing Date: Thu, 28 Nov 2024 17:03:51 -0500 Subject: [PATCH 046/125] 1. Change the data type of position from Arraylist to int[]. 2. Implemented most of the MoveInteractor, OutputBoundary and data. 3. Added a few more pieces --- src/main/java/use_case/move/MoveOutputBoundary.java | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/main/java/use_case/move/MoveOutputBoundary.java diff --git a/src/main/java/use_case/move/MoveOutputBoundary.java b/src/main/java/use_case/move/MoveOutputBoundary.java new file mode 100644 index 000000000..0e70da960 --- /dev/null +++ b/src/main/java/use_case/move/MoveOutputBoundary.java @@ -0,0 +1,6 @@ +package use_case.move; + +public interface MoveOutputBoundary { + void prepareSelect(MoveOutputdata outputdata); + void prepareMove(MoveOutputdata outputdata); +} From 55a1f9e0d8eed1ecec8c988373efc5b617e4d6bb Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Thu, 28 Nov 2024 17:23:44 -0500 Subject: [PATCH 047/125] refactor creation of LoggedInView into 'ShowProfileUseCaseFactory.java', showProfile usecase implemeted & add into Main_ck --- src/main/java/app/Main_ck.java | 14 +++- .../java/app/ShowProfileUseCaseFactory.java | 61 ++++++++++++++++ .../data_access/UserDataAccessObject.java | 4 +- .../profile/ProfileState.java | 4 -- .../profile/ProfileViewModel.java | 4 -- .../showProfile/ShowProfileController.java | 22 ++++++ .../showProfile/ShowProfilePresenter.java | 34 ++++++++- .../showProfile/ShowProfileState.java | 26 +++++++ .../showProfile/ShowProfileViewModel.java | 20 +++++- .../showProfile/ShowProfileInteractor.java | 4 +- .../showProfile/ShowProfileOutputData.java | 18 +++-- src/main/java/view/LoggedInView.java | 23 ++++++- src/main/java/view/ProfileView.java | 69 +++++++++++++++++++ 13 files changed, 278 insertions(+), 25 deletions(-) create mode 100644 src/main/java/app/ShowProfileUseCaseFactory.java delete mode 100644 src/main/java/interface_adapter/profile/ProfileState.java delete mode 100644 src/main/java/interface_adapter/profile/ProfileViewModel.java create mode 100644 src/main/java/view/ProfileView.java diff --git a/src/main/java/app/Main_ck.java b/src/main/java/app/Main_ck.java index 48d5ebaa9..8ab77e476 100644 --- a/src/main/java/app/Main_ck.java +++ b/src/main/java/app/Main_ck.java @@ -11,6 +11,7 @@ import interface_adapter.ViewManagerModel; import interface_adapter.logged_in.LoggedInViewModel; import interface_adapter.login.LoginViewModel; +import interface_adapter.showProfile.ShowProfileViewModel; import interface_adapter.signup.SignupViewModel; import view.*; @@ -38,15 +39,22 @@ public static void main(String[] args) { final LoginViewModel loginViewModel = new LoginViewModel(); final LoggedInViewModel loggedInViewModel = new LoggedInViewModel(); final SignupViewModel signupViewModel = new SignupViewModel(); + final ShowProfileViewModel showProfileViewModel = new ShowProfileViewModel(); final UserDataAccessObject userDataAccessObject = new UserDataAccessObject(); - final SignupView signupView = SignupApp.create(viewManagerModel, loginViewModel, signupViewModel, userDataAccessObject); - final LoginView loginView = LoginApp.create(viewManagerModel, loginViewModel, loggedInViewModel, userDataAccessObject); - final LoggedInView loggedInView = new LoggedInView(viewManagerModel, loggedInViewModel); + final SignupView signupView = SignupApp.create(viewManagerModel, loginViewModel, + signupViewModel, userDataAccessObject); + final LoginView loginView = LoginApp.create(viewManagerModel, loginViewModel, + loggedInViewModel, userDataAccessObject); + final LoggedInView loggedInView = ShowProfileUseCaseFactory.create(viewManagerModel, loggedInViewModel, + showProfileViewModel, userDataAccessObject); + final ProfileView profileView = new ProfileView(viewManagerModel, showProfileViewModel); + // final LoggedInView loggedInView = new LoggedInView(viewManagerModel, loggedInViewModel); views.add(signupView, signupView.getViewName()); views.add(loginView, loginView.getViewName()); views.add(loggedInView, loggedInView.getViewName()); + views.add(profileView, profileView.getViewName()); final CK_ChessAppBuilder chessAppBuilder = new CK_ChessAppBuilder(); chessAppBuilder.addChessDAO(new ChessDataAccessObject()) diff --git a/src/main/java/app/ShowProfileUseCaseFactory.java b/src/main/java/app/ShowProfileUseCaseFactory.java new file mode 100644 index 000000000..8d62b8ddb --- /dev/null +++ b/src/main/java/app/ShowProfileUseCaseFactory.java @@ -0,0 +1,61 @@ +package app; + +import interface_adapter.ViewManagerModel; +import interface_adapter.logged_in.LoggedInViewModel; +import interface_adapter.showProfile.ShowProfileController; +import interface_adapter.showProfile.ShowProfilePresenter; +import interface_adapter.showProfile.ShowProfileViewModel; +import use_case.showProfile.ShowProfileInputBoundary; +import use_case.showProfile.ShowProfileInteractor; +import use_case.showProfile.ShowProfileOutputBoundary; +import use_case.showProfile.ShowProfileUserDataAccessInterface; +import view.LoggedInView; + +/** + * This class contains the static factory function for creating the LoggedInView. + */ +public final class ShowProfileUseCaseFactory { + + /** Prevent instantiation. */ + private ShowProfileUseCaseFactory() { + + } + + /** + * Factory function for creating the LoggedInView. + * + * @param viewManagerModel the ViewManagerModel to inject into the LoggedInView + * @param loggedInViewModel the loggedInViewModel to inject into the LoggedInView + * @param showProfileViewModel + * @param userDataAccessObject the ChangePasswordUserDataAccessInterface to inject into the LoggedInView + * @return the LoggedInView created for the provided input classes + */ + public static LoggedInView create( + ViewManagerModel viewManagerModel, + LoggedInViewModel loggedInViewModel, + ShowProfileViewModel showProfileViewModel, + ShowProfileUserDataAccessInterface userDataAccessObject) { + + final ShowProfileController showProfileController = + createShowProfileUseCase(viewManagerModel, loggedInViewModel, + showProfileViewModel, userDataAccessObject); + + return new LoggedInView(viewManagerModel, loggedInViewModel, showProfileController); + + } + + private static ShowProfileController createShowProfileUseCase( + ViewManagerModel viewManagerModel, + LoggedInViewModel loggedInViewModel, + ShowProfileViewModel showProfileViewModel, + ShowProfileUserDataAccessInterface userDataAccessObject) { + + final ShowProfileOutputBoundary showProfileOutputBoundary = new ShowProfilePresenter(showProfileViewModel, + viewManagerModel); + + final ShowProfileInputBoundary showProfileInputInteractor = new ShowProfileInteractor(userDataAccessObject, + showProfileOutputBoundary); + + return new ShowProfileController(showProfileInputInteractor); + } +} diff --git a/src/main/java/data_access/UserDataAccessObject.java b/src/main/java/data_access/UserDataAccessObject.java index 9c9828f00..ab175b910 100644 --- a/src/main/java/data_access/UserDataAccessObject.java +++ b/src/main/java/data_access/UserDataAccessObject.java @@ -5,12 +5,14 @@ import entity.User; import use_case.login.LoginUserDataAccessInterface; +import use_case.showProfile.ShowProfileUserDataAccessInterface; import use_case.signup.SignupUserDataAccessInterface; /** * The DAO for user data. */ -public class UserDataAccessObject implements LoginUserDataAccessInterface, SignupUserDataAccessInterface { +public class UserDataAccessObject implements LoginUserDataAccessInterface, SignupUserDataAccessInterface, + ShowProfileUserDataAccessInterface { private final Map users = new HashMap<>(); private String currentUser; diff --git a/src/main/java/interface_adapter/profile/ProfileState.java b/src/main/java/interface_adapter/profile/ProfileState.java deleted file mode 100644 index 92c1602c0..000000000 --- a/src/main/java/interface_adapter/profile/ProfileState.java +++ /dev/null @@ -1,4 +0,0 @@ -package interface_adapter.profile; - -public class ProfileState { -} diff --git a/src/main/java/interface_adapter/profile/ProfileViewModel.java b/src/main/java/interface_adapter/profile/ProfileViewModel.java deleted file mode 100644 index 6888e9619..000000000 --- a/src/main/java/interface_adapter/profile/ProfileViewModel.java +++ /dev/null @@ -1,4 +0,0 @@ -package interface_adapter.profile; - -public class ProfileViewModel { -} diff --git a/src/main/java/interface_adapter/showProfile/ShowProfileController.java b/src/main/java/interface_adapter/showProfile/ShowProfileController.java index 69e15439a..6222b8f7a 100644 --- a/src/main/java/interface_adapter/showProfile/ShowProfileController.java +++ b/src/main/java/interface_adapter/showProfile/ShowProfileController.java @@ -1,4 +1,26 @@ package interface_adapter.showProfile; +import use_case.showProfile.ShowProfileInputBoundary; +import use_case.showProfile.ShowProfileInputData; + +/** + * The controller for the ShowProfile use case. + */ public class ShowProfileController { + + private final ShowProfileInputBoundary showProfileInputInteractor; + + public ShowProfileController(ShowProfileInputBoundary showProfileInteractor) { + this.showProfileInputInteractor = showProfileInteractor; + } + + /** + * Execute the showProfile use case. + * @param username the username of the user logging in + */ + public void execute(String username) { + final ShowProfileInputData showProfileInputData = new ShowProfileInputData(username); + + showProfileInputInteractor.execute(showProfileInputData); + } } diff --git a/src/main/java/interface_adapter/showProfile/ShowProfilePresenter.java b/src/main/java/interface_adapter/showProfile/ShowProfilePresenter.java index 90e50f57c..4ae8a8fbf 100644 --- a/src/main/java/interface_adapter/showProfile/ShowProfilePresenter.java +++ b/src/main/java/interface_adapter/showProfile/ShowProfilePresenter.java @@ -1,4 +1,36 @@ package interface_adapter.showProfile; -public class ShowProfilePresenter { +import interface_adapter.ViewManagerModel; +import use_case.showProfile.ShowProfileOutputBoundary; +import use_case.showProfile.ShowProfileOutputData; +import view.ViewManager; + +public class ShowProfilePresenter implements ShowProfileOutputBoundary { + + private final ShowProfileViewModel showProfileViewModel; + private final ViewManagerModel viewManagerModel; + + public ShowProfilePresenter(ShowProfileViewModel showProfileViewModel, ViewManagerModel viewManagerModel) { + this.showProfileViewModel = showProfileViewModel; + this.viewManagerModel = viewManagerModel; + } + + @Override + public void prepareSuccessView(ShowProfileOutputData outputData) { + // On success, switch to the Profile view. + + final ShowProfileState showProfileState = showProfileViewModel.getState(); + showProfileState.setUsername(outputData.getUsername()); + showProfileState.setRankPoint(outputData.getRankPoint()); + this.showProfileViewModel.setState(showProfileState); + this.showProfileViewModel.firePropertyChanged(); + + this.viewManagerModel.setState(showProfileViewModel.getViewName()); + this.viewManagerModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String errorMessage) { + + } } diff --git a/src/main/java/interface_adapter/showProfile/ShowProfileState.java b/src/main/java/interface_adapter/showProfile/ShowProfileState.java index 20d6acccf..3b523b0ed 100644 --- a/src/main/java/interface_adapter/showProfile/ShowProfileState.java +++ b/src/main/java/interface_adapter/showProfile/ShowProfileState.java @@ -1,4 +1,30 @@ package interface_adapter.showProfile; +/** + * The State information representing the logged-in user. + */ public class ShowProfileState { + private String username = ""; + private int rankPoint; + + public ShowProfileState() { + + } + + public void setUsername(String username) { + this.username = username; + } + + public void setRankPoint(int rankPoint) { + this.rankPoint = rankPoint; + } + + public String getUsername() { + return username; + } + + public int getRankPoint() { + return rankPoint; + } + } diff --git a/src/main/java/interface_adapter/showProfile/ShowProfileViewModel.java b/src/main/java/interface_adapter/showProfile/ShowProfileViewModel.java index af59a677a..d32b490ff 100644 --- a/src/main/java/interface_adapter/showProfile/ShowProfileViewModel.java +++ b/src/main/java/interface_adapter/showProfile/ShowProfileViewModel.java @@ -1,4 +1,22 @@ package interface_adapter.showProfile; -public class ShowProfileViewModel { +import interface_adapter.ViewModel; + +/** + * The View Model for the profile view. + */ +public class ShowProfileViewModel extends ViewModel { + + public ShowProfileViewModel() { + super("showProfile"); + setState(new ShowProfileState()); + } + + public String getUsername() { + return getState().getUsername(); + } + + public int getRankPoint() { + return getState().getRankPoint(); + } } diff --git a/src/main/java/use_case/showProfile/ShowProfileInteractor.java b/src/main/java/use_case/showProfile/ShowProfileInteractor.java index d1b35d38f..5acfc27e1 100644 --- a/src/main/java/use_case/showProfile/ShowProfileInteractor.java +++ b/src/main/java/use_case/showProfile/ShowProfileInteractor.java @@ -20,8 +20,8 @@ public void execute(ShowProfileInputData showProfileInputData) { // The following code only handle success use case call // Because I currently don't know what can cause this use case to fail final User user = userDataAccessObject.get(showProfileInputData.getUsername()); - final ShowProfileOutputData showProfileOutputData = new ShowProfileOutputData(user.getRankPointHistory(), - true); + final ShowProfileOutputData showProfileOutputData = + new ShowProfileOutputData(showProfileInputData.getUsername(), user.getCurrentRankPoint(), true); showProfilePresenter.prepareSuccessView(showProfileOutputData); } } diff --git a/src/main/java/use_case/showProfile/ShowProfileOutputData.java b/src/main/java/use_case/showProfile/ShowProfileOutputData.java index 16d639fa5..3198e2fae 100644 --- a/src/main/java/use_case/showProfile/ShowProfileOutputData.java +++ b/src/main/java/use_case/showProfile/ShowProfileOutputData.java @@ -1,22 +1,26 @@ package use_case.showProfile; -import java.util.ArrayList; - /** * Output Data for the ShowProfile Use case. */ public class ShowProfileOutputData { - private final ArrayList rankPointHistory; + private final String username; + private final int rankPoint; private final boolean useCaseSucceeded; - public ShowProfileOutputData(ArrayList rankPointHistory, boolean useCaseSucceeded) { - this.rankPointHistory = rankPointHistory; + public ShowProfileOutputData(String username, int rankPoint, boolean useCaseSucceeded) { + this.username = username; + this.rankPoint = rankPoint; this.useCaseSucceeded = useCaseSucceeded; } - public ArrayList getRankPointHistory() { - return rankPointHistory; + public int getRankPoint() { + return rankPoint; + } + + public String getUsername() { + return username; } } diff --git a/src/main/java/view/LoggedInView.java b/src/main/java/view/LoggedInView.java index 0845f6269..7e3bb6f9a 100644 --- a/src/main/java/view/LoggedInView.java +++ b/src/main/java/view/LoggedInView.java @@ -12,9 +12,11 @@ import javax.swing.JPanel; import javax.swing.JTextField; +import interface_adapter.ViewManagerModel; import interface_adapter.logged_in.LoggedInState; import interface_adapter.logged_in.LoggedInViewModel; -import interface_adapter.ViewManagerModel; +import interface_adapter.login.LoginState; +import interface_adapter.showProfile.ShowProfileController; /** * The View for when the user is logged into the program. @@ -32,9 +34,12 @@ public class LoggedInView extends JPanel implements ActionListener, PropertyChan private final JTextField passwordInputField = new JTextField(15); private final JButton startChess; private final JButton showProfile; + private final ShowProfileController showProfileController; - public LoggedInView(ViewManagerModel viewManagerModel, LoggedInViewModel loggedInViewModel) { + public LoggedInView(ViewManagerModel viewManagerModel, LoggedInViewModel loggedInViewModel, + ShowProfileController showProfileController) { this.loggedInViewModel = loggedInViewModel; + this.showProfileController = showProfileController; this.loggedInViewModel.addPropertyChangeListener(this); final JLabel title = new JLabel("Logged In Screen"); @@ -69,6 +74,20 @@ public LoggedInView(ViewManagerModel viewManagerModel, LoggedInViewModel loggedI } ); + showProfile.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(showProfile)) { + final LoggedInState currentState = loggedInViewModel.getState(); + + showProfileController.execute( + currentState.getUsername() + ); + } + } + } + ); + this.add(title); this.add(usernameInfo); this.add(username); diff --git a/src/main/java/view/ProfileView.java b/src/main/java/view/ProfileView.java new file mode 100644 index 000000000..8f7c740c4 --- /dev/null +++ b/src/main/java/view/ProfileView.java @@ -0,0 +1,69 @@ +package view; + +import interface_adapter.ViewManagerModel; +import interface_adapter.logged_in.LoggedInViewModel; +import interface_adapter.showProfile.ShowProfileState; +import interface_adapter.showProfile.ShowProfileViewModel; + +import javax.swing.*; +import javax.swing.text.View; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Observer; + +/** + * The view of user profile. + */ +public class ProfileView extends JPanel implements ActionListener, PropertyChangeListener { + + private final String viewName = "showProfile"; + private final ShowProfileViewModel showProfileViewModel; + + private final JLabel username; + private final JLabel currentRankPoint; + + public ProfileView(ViewManagerModel viewManagerModel, ShowProfileViewModel showProfileViewModel) { + this.showProfileViewModel = showProfileViewModel; + this.showProfileViewModel.addPropertyChangeListener(this); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + final JLabel title = new JLabel("Profile"); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + + final JLabel usernameInfo = new JLabel("Currently logged in: "); + username = new JLabel(); + + final JLabel rankPointInfo = new JLabel("Current rank point: "); + currentRankPoint = new JLabel(); + + this.add(title); + this.add(usernameInfo); + this.add(username); + this.add(rankPointInfo); + this.add(currentRankPoint); + } + + /** + * React to a button click that results in evt. + * @param evt the ActionEvent to react to + */ + public void actionPerformed(ActionEvent evt) { + System.out.println("Click " + evt.getActionCommand()); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + final ShowProfileState showProfileState = (ShowProfileState) evt.getNewValue(); + username.setText(showProfileState.getUsername()); + currentRankPoint.setText(String.valueOf(showProfileState.getRankPoint())); + } + + public String getViewName() { + return viewName; + } + +} From 794e4ec24c7df1c8d1189f526e307a7e2ccca519 Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Thu, 28 Nov 2024 18:42:22 -0500 Subject: [PATCH 048/125] Refactor LoginUseCaseFactory, SignupUseCaseFactory --- src/main/java/app/{LoginApp.java => LoginUseCaseFactory.java} | 4 ++-- src/main/java/app/Main_ck.java | 4 ++-- .../java/app/{SignupApp.java => SignupUseCaseFactory.java} | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename src/main/java/app/{LoginApp.java => LoginUseCaseFactory.java} (96%) rename src/main/java/app/{SignupApp.java => SignupUseCaseFactory.java} (96%) diff --git a/src/main/java/app/LoginApp.java b/src/main/java/app/LoginUseCaseFactory.java similarity index 96% rename from src/main/java/app/LoginApp.java rename to src/main/java/app/LoginUseCaseFactory.java index 67af2ad51..4685a7c69 100644 --- a/src/main/java/app/LoginApp.java +++ b/src/main/java/app/LoginUseCaseFactory.java @@ -14,10 +14,10 @@ /** * This class contains the static factory function for creating the LoginView. */ -public final class LoginApp { +public final class LoginUseCaseFactory { /** Prevent instantiation. */ - private LoginApp() { + private LoginUseCaseFactory() { } diff --git a/src/main/java/app/Main_ck.java b/src/main/java/app/Main_ck.java index 48d5ebaa9..577dbf11d 100644 --- a/src/main/java/app/Main_ck.java +++ b/src/main/java/app/Main_ck.java @@ -40,8 +40,8 @@ public static void main(String[] args) { final SignupViewModel signupViewModel = new SignupViewModel(); final UserDataAccessObject userDataAccessObject = new UserDataAccessObject(); - final SignupView signupView = SignupApp.create(viewManagerModel, loginViewModel, signupViewModel, userDataAccessObject); - final LoginView loginView = LoginApp.create(viewManagerModel, loginViewModel, loggedInViewModel, userDataAccessObject); + final SignupView signupView = SignupUseCaseFactory.create(viewManagerModel, loginViewModel, signupViewModel, userDataAccessObject); + final LoginView loginView = LoginUseCaseFactory.create(viewManagerModel, loginViewModel, loggedInViewModel, userDataAccessObject); final LoggedInView loggedInView = new LoggedInView(viewManagerModel, loggedInViewModel); views.add(signupView, signupView.getViewName()); diff --git a/src/main/java/app/SignupApp.java b/src/main/java/app/SignupUseCaseFactory.java similarity index 96% rename from src/main/java/app/SignupApp.java rename to src/main/java/app/SignupUseCaseFactory.java index b43fd290f..06dfe8f35 100644 --- a/src/main/java/app/SignupApp.java +++ b/src/main/java/app/SignupUseCaseFactory.java @@ -14,10 +14,10 @@ /** * This class contains the static factory function for creating the SignupView. */ -public final class SignupApp { +public final class SignupUseCaseFactory { /** Prevent instantiation. */ - private SignupApp() { + private SignupUseCaseFactory() { } From 4fe9cc8b4c60945bc72a7f5f345dc6d54578798a Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Thu, 28 Nov 2024 20:05:55 -0500 Subject: [PATCH 049/125] README.md update --- README.md | 20 ++++++++++++++++++++ src/main/java/app/CK_ChessAppBuilder.java | 4 ++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9028e9600..dfb53ba9b 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,12 @@ John Ding - J0hnDing Yann Chi - YannChi22 +## Table of content + +[Project Domain](https://github.com/DDMMMAA/CSC207-Team179#projectdomain) +[Project Domain](https://github.com/DDMMMAA/CSC207-Team179#usecases) + + ## Project Domain The domain will be able to generate random chess puzzles with options for daily, random puzzles, or specifically themed puzzles. @@ -19,6 +25,20 @@ A user will be able to view their puzzle statistics or review past puzzles withi Users should have the option to log in or create an account [built into the lichess api]. If a user is logged in, they should be able to access any past puzzle scores or game histories they’ve played on that account. +## Instructions + +Clone ```main``` branch, then run ```MainChessAPP.java``` in ```src/main/java/app``` + +## Use Cases + +### Signup & Login + +### Show Profile + +### Generate daily puzzle + +### Step by step move + ## User Stories Group User Story. Tom generate a chess puzzle, solve it step by step, and eventually win. diff --git a/src/main/java/app/CK_ChessAppBuilder.java b/src/main/java/app/CK_ChessAppBuilder.java index eea64bdf6..143a69bee 100644 --- a/src/main/java/app/CK_ChessAppBuilder.java +++ b/src/main/java/app/CK_ChessAppBuilder.java @@ -6,7 +6,7 @@ import interface_adapter.move.MovePresenter; import interface_adapter.move.MoveViewModel; import use_case.move.MoveInteractor; -import use_case.move.MoveOutPutBoundary; +import use_case.move.MoveOutputBoundary; import view.ChessBoardView; /** @@ -37,7 +37,7 @@ public CK_ChessAppBuilder addChessDAO(ChessDataAccessObject chessDataAccess) { * @return this builder */ public CK_ChessAppBuilder addMoveUseCase() { - final MoveOutPutBoundary moveOutPutBoundary = new MovePresenter(moveViewModel, viewManagerModel); + final MoveOutputBoundary moveOutPutBoundary = new MovePresenter(moveViewModel, viewManagerModel); moveInteractor = new MoveInteractor( chessDataAccessObject, moveOutPutBoundary); From 13ef21db569bc5bd8ad472a37a6493147657c7c2 Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Thu, 28 Nov 2024 20:09:26 -0500 Subject: [PATCH 050/125] README.md update --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index dfb53ba9b..3dde7b139 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Yann Chi - YannChi22 ## Table of content [Project Domain](https://github.com/DDMMMAA/CSC207-Team179#projectdomain) + [Project Domain](https://github.com/DDMMMAA/CSC207-Team179#usecases) @@ -31,14 +32,29 @@ Clone ```main``` branch, then run ```MainChessAPP.java``` in ```src/main/java/ap ## Use Cases + + + ### Signup & Login + + + ### Show Profile + + + ### Generate daily puzzle + + + ### Step by step move + + + ## User Stories Group User Story. Tom generate a chess puzzle, solve it step by step, and eventually win. From 4818aef328b5db14a9f10601f21b8a6d0bb0c8cd Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Thu, 28 Nov 2024 20:12:06 -0500 Subject: [PATCH 051/125] README.md update --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3dde7b139..4741c1d02 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,9 @@ Yann Chi - YannChi22 [Project Domain](https://github.com/DDMMMAA/CSC207-Team179#projectdomain) -[Project Domain](https://github.com/DDMMMAA/CSC207-Team179#usecases) +[Instructions](https://github.com/DDMMMAA/CSC207-Team179#instructions) + +[Use Cases](https://github.com/DDMMMAA/CSC207-Team179#usecases) ## Project Domain From 5c3da49be7b4a8b94577aba0a6bc3fb45f7fe1c1 Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Thu, 28 Nov 2024 20:42:55 -0500 Subject: [PATCH 052/125] important!!!: new 'Board' and 'Game' is created in addMoveUseCase method of AppBuilder to make 'main' app run, once 'dail_puzzle' use case finished, 'dail_puzzle' use case is responsible for create new 'Board' and 'Game'. README.md update --- README.md | 21 +++++++++++++-------- src/main/java/app/CK_ChessAppBuilder.java | 6 +++++- src/main/java/app/ChessAppBuilder.java | 6 +++++- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 4741c1d02..f4008df4f 100644 --- a/README.md +++ b/README.md @@ -14,23 +14,28 @@ Yann Chi - YannChi22 ## Table of content -[Project Domain](https://github.com/DDMMMAA/CSC207-Team179#projectdomain) ++ [Project Domain](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#project-domain) -[Instructions](https://github.com/DDMMMAA/CSC207-Team179#instructions) ++ [Instructions](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#instructions) + + [Signup & Login](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#signup--login) + + [Show Profile](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#show-profile) + + [Generate Daily Puzzle](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#generate-daily-puzzle) + + [Step by Step Move](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#generate-daily-puzzle) ++ [Use Cases](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#use-cases) -[Use Cases](https://github.com/DDMMMAA/CSC207-Team179#usecases) +## About this project -## Project Domain - -The domain will be able to generate random chess puzzles with options for daily, random puzzles, or specifically themed puzzles. +This app/project is able to generate random chess puzzles with options for daily, random puzzles, or specifically themed puzzles. A user will be able to view their puzzle statistics or review past puzzles within the current session of the program. Users should have the option to log in or create an account [built into the lichess api]. If a user is logged in, they should be able to access any past puzzle scores or game histories they’ve played on that account. -## Instructions +## Installation + +To Start: Clone ```main``` branch, then run ```MainChessAPP.java``` in ```src/main/java/app``` -Clone ```main``` branch, then run ```MainChessAPP.java``` in ```src/main/java/app``` +To close: Left click ```X``` icon at top right. ## Use Cases diff --git a/src/main/java/app/CK_ChessAppBuilder.java b/src/main/java/app/CK_ChessAppBuilder.java index 143a69bee..e7012380a 100644 --- a/src/main/java/app/CK_ChessAppBuilder.java +++ b/src/main/java/app/CK_ChessAppBuilder.java @@ -1,6 +1,8 @@ package app; import data_access.ChessDataAccessObject; +import entity.Board; +import entity.Game; import interface_adapter.ViewManagerModel; import interface_adapter.move.MoveController; import interface_adapter.move.MovePresenter; @@ -38,8 +40,10 @@ public CK_ChessAppBuilder addChessDAO(ChessDataAccessObject chessDataAccess) { */ public CK_ChessAppBuilder addMoveUseCase() { final MoveOutputBoundary moveOutPutBoundary = new MovePresenter(moveViewModel, viewManagerModel); + Board board = new Board(); + Game game = new Game(board, true); moveInteractor = new MoveInteractor( - chessDataAccessObject, moveOutPutBoundary); + chessDataAccessObject, moveOutPutBoundary, game); final MoveController moveController = new MoveController(moveInteractor); chessBoardView.setMoveController(moveController); diff --git a/src/main/java/app/ChessAppBuilder.java b/src/main/java/app/ChessAppBuilder.java index 42dfd6085..752666d46 100644 --- a/src/main/java/app/ChessAppBuilder.java +++ b/src/main/java/app/ChessAppBuilder.java @@ -4,6 +4,8 @@ import javax.swing.WindowConstants; import data_access.ChessDataAccessObject; +import entity.Board; +import entity.Game; import interface_adapter.ViewManagerModel; import interface_adapter.move.MoveController; import interface_adapter.move.MovePresenter; @@ -41,8 +43,10 @@ public ChessAppBuilder addChessDAO(ChessDataAccessObject chessDataAccess) { */ public ChessAppBuilder addMoveUseCase() { final MoveOutputBoundary moveOutPutBoundary = new MovePresenter(moveViewModel, viewManagerModel); + Board board = new Board(); + Game game = new Game(board, true); moveInteractor = new MoveInteractor( - chessDataAccessObject, moveOutPutBoundary); + chessDataAccessObject, moveOutPutBoundary, game); final MoveController moveController = new MoveController(moveInteractor); chessBoardView.setMoveController(moveController); From 20c8111fab3a261071bace6c628547cce9cdae85 Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Fri, 29 Nov 2024 18:53:40 -0500 Subject: [PATCH 053/125] LoggedInView minor change --- src/main/java/view/LoggedInView.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/main/java/view/LoggedInView.java b/src/main/java/view/LoggedInView.java index 4e4d9711b..38fb2f381 100644 --- a/src/main/java/view/LoggedInView.java +++ b/src/main/java/view/LoggedInView.java @@ -6,11 +6,9 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; -import javax.swing.JTextField; import interface_adapter.logged_in.LoggedInState; import interface_adapter.logged_in.LoggedInViewModel; @@ -29,7 +27,6 @@ public class LoggedInView extends JPanel implements ActionListener, PropertyChan private final JButton logOut; - private final JTextField passwordInputField = new JTextField(15); private final JButton startChess; public LoggedInView(ViewManagerModel viewManagerModel, LoggedInViewModel loggedInViewModel) { @@ -39,9 +36,6 @@ public LoggedInView(ViewManagerModel viewManagerModel, LoggedInViewModel loggedI final JLabel title = new JLabel("Logged In Screen"); title.setAlignmentX(Component.CENTER_ALIGNMENT); - final LabelTextPanel passwordInfo = new LabelTextPanel( - new JLabel("Password"), passwordInputField); - final JLabel usernameInfo = new JLabel("Currently logged in: "); username = new JLabel(); @@ -54,8 +48,6 @@ public LoggedInView(ViewManagerModel viewManagerModel, LoggedInViewModel loggedI logOut.addActionListener(this); - this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - startChess.addActionListener( evt -> { if (evt.getSource().equals(startChess)) { @@ -69,7 +61,6 @@ public LoggedInView(ViewManagerModel viewManagerModel, LoggedInViewModel loggedI this.add(usernameInfo); this.add(username); - this.add(passwordInfo); this.add(passwordErrorField); this.add(buttons); } From 4d93b7990dbebf954fdfe44c98e3526359be8d47 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Sat, 30 Nov 2024 11:25:20 -0500 Subject: [PATCH 054/125] Minor adjustment to Yann's user story. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f4008df4f..014ac7975 100644 --- a/README.md +++ b/README.md @@ -69,5 +69,5 @@ Group User Story. Tom generate a chess puzzle, solve it step by step, and eventu 1. John wants to play a chess puzzle. He opens the chess puzzle player and clicks generate puzzle of the day. The chess puzzle of the day loads on screen. [Michelle’s Story] 2. Tom and Tim argued about who is a better chess player, so they decided to compare their Rank point of Ranking system. [Jiaqi Ma’s Story] 3. As Mary hears about this chess puzzle, she wants to create an account and log in to start a puzzle. [Chihana’s Story] -4. Andy is learning chess, and his teacher use this program to check Andy's learning progress, by looking at past statistics of chess puzzles. The teacher can search up Andy's user account using the username. [Yann Chi's Story] +4. Andy is learning chess, and he can use this program to check his learning progress, by looking at past statistics of chess puzzles. He can search up his user account using the username. [Yann Chi's Story] 5. Felix wants to see the possible moves he can make with one piece, so he click on that piece and the possible cells will be indicated. [John’s Story] From 1fb16a33b79d1c61a2efc2a14891d6424b352fc8 Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Sat, 30 Nov 2024 13:36:45 -0500 Subject: [PATCH 055/125] README.me update --- README.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f4008df4f..7f4b26318 100644 --- a/README.md +++ b/README.md @@ -33,11 +33,16 @@ If a user is logged in, they should be able to access any past puzzle scores or ## Installation -To Start: Clone ```main``` branch, then run ```MainChessAPP.java``` in ```src/main/java/app``` +To Start: Clone ```main``` branch into your favorite JAVA IDE, then run ```MainChessAPP.java``` in ```src/main/java/app``` +``` +git clone https://github.com/DDMMMAA/CSC207-Team179.git +``` To close: Left click ```X``` icon at top right. -## Use Cases +Note: No additional package needed + +## Use Cases (Features) @@ -59,8 +64,18 @@ To close: Left click ```X``` icon at top right. ### Step by step move +## Usage Guide + +This meant to me used in order of ```Signup & Login``` → ```Generate daily puzzle``` → ```Step by step move``` +(Please refer to above ```use cases (Features)``` for detail of each use case) + +## Feedback + +Plead use github [Discussion board](https://github.com/DDMMMAA/CSC207-Team179/discussions) to submit your feedback. +Simply start a new discussion with appropriate title (eg., associated use case). +## This project is close for contributions ## User Stories From b4c5f9d9fe15af2f8824f616d5d911bb4fcb2284 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Sat, 30 Nov 2024 15:04:20 -0500 Subject: [PATCH 056/125] Added Query use case and added button of show rank history in view. --- .../query/QueryController.java | 4 ++++ .../query/QueryPresenter.java | 4 ++++ .../query/QueryProfileViewModel.java | 4 ++++ .../interface_adapter/query/QueryState.java | 4 ++++ .../query/QueryDataAccessInterface.java | 4 ++++ .../use_case/query/QueryInputBoundary.java | 18 ++++++++++++++++++ .../java/use_case/query/QueryInputData.java | 15 +++++++++++++++ .../java/use_case/query/QueryInteractor.java | 4 ++++ .../use_case/query/QueryOutputBoundary.java | 4 ++++ src/main/java/view/LoggedInView.java | 19 +++++++++++++++++++ 10 files changed, 80 insertions(+) create mode 100644 src/main/java/interface_adapter/query/QueryController.java create mode 100644 src/main/java/interface_adapter/query/QueryPresenter.java create mode 100644 src/main/java/interface_adapter/query/QueryProfileViewModel.java create mode 100644 src/main/java/interface_adapter/query/QueryState.java create mode 100644 src/main/java/use_case/query/QueryDataAccessInterface.java create mode 100644 src/main/java/use_case/query/QueryInputBoundary.java create mode 100644 src/main/java/use_case/query/QueryInputData.java create mode 100644 src/main/java/use_case/query/QueryInteractor.java create mode 100644 src/main/java/use_case/query/QueryOutputBoundary.java diff --git a/src/main/java/interface_adapter/query/QueryController.java b/src/main/java/interface_adapter/query/QueryController.java new file mode 100644 index 000000000..5fa449029 --- /dev/null +++ b/src/main/java/interface_adapter/query/QueryController.java @@ -0,0 +1,4 @@ +package interface_adapter.query; + +public class QueryController { +} diff --git a/src/main/java/interface_adapter/query/QueryPresenter.java b/src/main/java/interface_adapter/query/QueryPresenter.java new file mode 100644 index 000000000..14b19dada --- /dev/null +++ b/src/main/java/interface_adapter/query/QueryPresenter.java @@ -0,0 +1,4 @@ +package interface_adapter.query; + +public class QueryPresenter { +} diff --git a/src/main/java/interface_adapter/query/QueryProfileViewModel.java b/src/main/java/interface_adapter/query/QueryProfileViewModel.java new file mode 100644 index 000000000..0673fc325 --- /dev/null +++ b/src/main/java/interface_adapter/query/QueryProfileViewModel.java @@ -0,0 +1,4 @@ +package interface_adapter.query; + +public class QueryProfileViewModel { +} diff --git a/src/main/java/interface_adapter/query/QueryState.java b/src/main/java/interface_adapter/query/QueryState.java new file mode 100644 index 000000000..bd9021aa8 --- /dev/null +++ b/src/main/java/interface_adapter/query/QueryState.java @@ -0,0 +1,4 @@ +package interface_adapter.query; + +public class QueryState { +} diff --git a/src/main/java/use_case/query/QueryDataAccessInterface.java b/src/main/java/use_case/query/QueryDataAccessInterface.java new file mode 100644 index 000000000..dc6ec1f12 --- /dev/null +++ b/src/main/java/use_case/query/QueryDataAccessInterface.java @@ -0,0 +1,4 @@ +package use_case.query; + +public interface QueryDataAccessInterface { +} diff --git a/src/main/java/use_case/query/QueryInputBoundary.java b/src/main/java/use_case/query/QueryInputBoundary.java new file mode 100644 index 000000000..743cc81ea --- /dev/null +++ b/src/main/java/use_case/query/QueryInputBoundary.java @@ -0,0 +1,18 @@ +package use_case.query; + +/** + * Input Boundary for actions which are related to searching user. + */ +public interface QueryInputBoundary { + + /** + * Executes the search User use case. + * @param username the input data + */ + void execute(String username); + + /** + * Executes the switch to login view use case. + */ + void switchToLoginView(); +} \ No newline at end of file diff --git a/src/main/java/use_case/query/QueryInputData.java b/src/main/java/use_case/query/QueryInputData.java new file mode 100644 index 000000000..69b1f8694 --- /dev/null +++ b/src/main/java/use_case/query/QueryInputData.java @@ -0,0 +1,15 @@ +package use_case.query; + +/** + * The Input Data for the SearchUser use case. + */ + +public class QueryInputData { + private final String username; + + public QueryInputData(String username) { + this.username = username; } + + public String getUsername() { + return username; } +} diff --git a/src/main/java/use_case/query/QueryInteractor.java b/src/main/java/use_case/query/QueryInteractor.java new file mode 100644 index 000000000..dd3bea5eb --- /dev/null +++ b/src/main/java/use_case/query/QueryInteractor.java @@ -0,0 +1,4 @@ +package use_case.query; + +public class QueryInteractor { +} diff --git a/src/main/java/use_case/query/QueryOutputBoundary.java b/src/main/java/use_case/query/QueryOutputBoundary.java new file mode 100644 index 000000000..aad4accd5 --- /dev/null +++ b/src/main/java/use_case/query/QueryOutputBoundary.java @@ -0,0 +1,4 @@ +package use_case.query; + +public interface QueryOutputBoundary { +} diff --git a/src/main/java/view/LoggedInView.java b/src/main/java/view/LoggedInView.java index 7e3bb6f9a..c4a7cdc6c 100644 --- a/src/main/java/view/LoggedInView.java +++ b/src/main/java/view/LoggedInView.java @@ -16,6 +16,7 @@ import interface_adapter.logged_in.LoggedInState; import interface_adapter.logged_in.LoggedInViewModel; import interface_adapter.login.LoginState; +import interface_adapter.query.QueryController; import interface_adapter.showProfile.ShowProfileController; /** @@ -34,6 +35,7 @@ public class LoggedInView extends JPanel implements ActionListener, PropertyChan private final JTextField passwordInputField = new JTextField(15); private final JButton startChess; private final JButton showProfile; + private final JButton showRankHistory; private final ShowProfileController showProfileController; public LoggedInView(ViewManagerModel viewManagerModel, LoggedInViewModel loggedInViewModel, @@ -55,11 +57,14 @@ public LoggedInView(ViewManagerModel viewManagerModel, LoggedInViewModel loggedI logOut = new JButton("Log Out"); buttons.add(logOut); + showRankHistory = new JButton("Show Rank History"); + showProfile = new JButton("Show Profile"); startChess = new JButton("Start Chess Game"); buttons.add(startChess); buttons.add(showProfile); + buttons.add(showRankHistory); logOut.addActionListener(this); @@ -88,6 +93,20 @@ public void actionPerformed(ActionEvent evt) { } ); + showRankHistory.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(showRankHistory)) { + final LoggedInState currentState = loggedInViewModel.getState(); + + QueryController.execute( + currentState.getUsername() + ) + } + } + } + ) + this.add(title); this.add(usernameInfo); this.add(username); From 0750870834487c869270df628aacb74b5b88e640 Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Sat, 30 Nov 2024 16:24:49 -0500 Subject: [PATCH 057/125] LoggedInView minor change --- src/main/java/app/Main_ck.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/app/Main_ck.java b/src/main/java/app/Main_ck.java index 09e0fe1bc..cb7cd2189 100644 --- a/src/main/java/app/Main_ck.java +++ b/src/main/java/app/Main_ck.java @@ -43,9 +43,9 @@ public static void main(String[] args) { final UserDataAccessObject userDataAccessObject = new UserDataAccessObject(); - final SignupView signupView = SignupApp.create(viewManagerModel, loginViewModel, + final SignupView signupView = SignupUseCaseFactory.create(viewManagerModel, loginViewModel, signupViewModel, userDataAccessObject); - final LoginView loginView = LoginApp.create(viewManagerModel, loginViewModel, + final LoginView loginView = LoginUseCaseFactory.create(viewManagerModel, loginViewModel, loggedInViewModel, userDataAccessObject); final LoggedInView loggedInView = ShowProfileUseCaseFactory.create(viewManagerModel, loggedInViewModel, showProfileViewModel, userDataAccessObject); From 005e095316fcd3ff64a7ecaf1d618408d483270e Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Sat, 30 Nov 2024 16:42:47 -0500 Subject: [PATCH 058/125] README edit --- README.md | 4 ++++ src/main/java/interface_adapter/move/MovePresenter.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f4008df4f..1376e8fc7 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,11 @@ To close: Left click ```X``` icon at top right. ### Signup & Login +This feature allows users to signup by creating username and password and login to the account created. +To Signup: Enter username and password(two times) to be used for an account, and click ```Signup``` to confirm signup. + +To Login: Click ```Login``` to navigate to a login page, enter username and password for the account, and click ```Login``` to confirm login. ### Show Profile diff --git a/src/main/java/interface_adapter/move/MovePresenter.java b/src/main/java/interface_adapter/move/MovePresenter.java index 9f51108b9..9380b8227 100644 --- a/src/main/java/interface_adapter/move/MovePresenter.java +++ b/src/main/java/interface_adapter/move/MovePresenter.java @@ -1,6 +1,6 @@ package interface_adapter.move; -import chariot.model.MoveInfo; +//import chariot.model.MoveInfo; import interface_adapter.ViewManagerModel; import use_case.move.MoveInputdata; import use_case.move.MoveOutputBoundary; From d5c4afb368e168a10a967be7b910b94473291c2c Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Sat, 30 Nov 2024 19:10:29 -0500 Subject: [PATCH 059/125] Attempt to create switchToSignUpPage --- src/main/java/app/Main_ck.java | 4 ++-- .../java/app/ShowProfileUseCaseFactory.java | 24 ++++++++++++++++++- .../logged_in/LoggedInController.java | 22 +++++++++++++++++ .../logged_in/LoggedInPresenter.java | 15 ++++++++++-- .../logged_in/LoggedInInputBoundary.java | 11 +++++++++ .../logged_in/LoggedInInteractor.java | 17 +++++++++++++ .../logged_in/LoggedInOutputBoundary.java | 8 +++++++ src/main/java/view/LoggedInView.java | 21 ++++++++++++---- src/main/java/view/SignupView.java | 4 +++- 9 files changed, 116 insertions(+), 10 deletions(-) create mode 100644 src/main/java/interface_adapter/logged_in/LoggedInController.java create mode 100644 src/main/java/use_case/logged_in/LoggedInInputBoundary.java create mode 100644 src/main/java/use_case/logged_in/LoggedInInteractor.java create mode 100644 src/main/java/use_case/logged_in/LoggedInOutputBoundary.java diff --git a/src/main/java/app/Main_ck.java b/src/main/java/app/Main_ck.java index cb7cd2189..463a744e7 100644 --- a/src/main/java/app/Main_ck.java +++ b/src/main/java/app/Main_ck.java @@ -34,7 +34,7 @@ public static void main(String[] args) { frame.add(views); final ViewManagerModel viewManagerModel = new ViewManagerModel(); - final ViewManager viewManager = new ViewManager(views, cardLayout, viewManagerModel); + new ViewManager(views, cardLayout, viewManagerModel); final LoginViewModel loginViewModel = new LoginViewModel(); final LoggedInViewModel loggedInViewModel = new LoggedInViewModel(); @@ -48,7 +48,7 @@ public static void main(String[] args) { final LoginView loginView = LoginUseCaseFactory.create(viewManagerModel, loginViewModel, loggedInViewModel, userDataAccessObject); final LoggedInView loggedInView = ShowProfileUseCaseFactory.create(viewManagerModel, loggedInViewModel, - showProfileViewModel, userDataAccessObject); + signupViewModel, showProfileViewModel, userDataAccessObject); final ProfileView profileView = new ProfileView(viewManagerModel, showProfileViewModel); // final LoggedInView loggedInView = new LoggedInView(viewManagerModel, loggedInViewModel); diff --git a/src/main/java/app/ShowProfileUseCaseFactory.java b/src/main/java/app/ShowProfileUseCaseFactory.java index 8d62b8ddb..ec48b017e 100644 --- a/src/main/java/app/ShowProfileUseCaseFactory.java +++ b/src/main/java/app/ShowProfileUseCaseFactory.java @@ -1,10 +1,16 @@ package app; import interface_adapter.ViewManagerModel; +import interface_adapter.logged_in.LoggedInController; +import interface_adapter.logged_in.LoggedInPresenter; import interface_adapter.logged_in.LoggedInViewModel; import interface_adapter.showProfile.ShowProfileController; import interface_adapter.showProfile.ShowProfilePresenter; import interface_adapter.showProfile.ShowProfileViewModel; +import interface_adapter.signup.SignupViewModel; +import use_case.logged_in.LoggedInInputBoundary; +import use_case.logged_in.LoggedInInteractor; +import use_case.logged_in.LoggedInOutputBoundary; import use_case.showProfile.ShowProfileInputBoundary; import use_case.showProfile.ShowProfileInteractor; import use_case.showProfile.ShowProfileOutputBoundary; @@ -26,6 +32,7 @@ private ShowProfileUseCaseFactory() { * * @param viewManagerModel the ViewManagerModel to inject into the LoggedInView * @param loggedInViewModel the loggedInViewModel to inject into the LoggedInView + * @param signupViewModel * @param showProfileViewModel * @param userDataAccessObject the ChangePasswordUserDataAccessInterface to inject into the LoggedInView * @return the LoggedInView created for the provided input classes @@ -33,6 +40,7 @@ private ShowProfileUseCaseFactory() { public static LoggedInView create( ViewManagerModel viewManagerModel, LoggedInViewModel loggedInViewModel, + SignupViewModel signupViewModel, ShowProfileViewModel showProfileViewModel, ShowProfileUserDataAccessInterface userDataAccessObject) { @@ -40,8 +48,9 @@ public static LoggedInView create( createShowProfileUseCase(viewManagerModel, loggedInViewModel, showProfileViewModel, userDataAccessObject); - return new LoggedInView(viewManagerModel, loggedInViewModel, showProfileController); + final LoggedInController loggedInController = createLoggedInUseCase(viewManagerModel, loggedInViewModel, signupViewModel) + return new LoggedInView(viewManagerModel, loggedInController, loggedInViewModel, showProfileController); } private static ShowProfileController createShowProfileUseCase( @@ -58,4 +67,17 @@ private static ShowProfileController createShowProfileUseCase( return new ShowProfileController(showProfileInputInteractor); } + + private static LoggedInController createLoggedInUseCase( + ViewManagerModel viewManagerModel, + LoggedInViewModel loggedInViewModel, + SignupViewModel signupViewModel){ + + final LoggedInOutputBoundary loggedInOutputBoundary = new LoggedInPresenter(viewManagerModel, loggedInViewModel, + signupViewModel); + + final LoggedInInputBoundary loggedInInputBoundary = new LoggedInInteractor(loggedInOutputBoundary); + + return new LoggedInController(loggedInInputBoundary); + } } diff --git a/src/main/java/interface_adapter/logged_in/LoggedInController.java b/src/main/java/interface_adapter/logged_in/LoggedInController.java new file mode 100644 index 000000000..3f214dde7 --- /dev/null +++ b/src/main/java/interface_adapter/logged_in/LoggedInController.java @@ -0,0 +1,22 @@ +package interface_adapter.logged_in; + +import use_case.logged_in.LoggedInInputBoundary; + +/** + * Controller for the Signup Use Case. + */ +public class LoggedInController { + + private final LoggedInInputBoundary userLoggedInUseCaseInteractor; + + public LoggedInController(LoggedInInputBoundary userLoggedInUseCaseInteractor) { + this.userLoggedInUseCaseInteractor = userLoggedInUseCaseInteractor; + } + + /** + * Executes the "switch to LoginView" Use Case. + */ + public void switchToSignUpView() { + userLoggedInUseCaseInteractor.switchToSignUpView(); + } +} diff --git a/src/main/java/interface_adapter/logged_in/LoggedInPresenter.java b/src/main/java/interface_adapter/logged_in/LoggedInPresenter.java index 8e91fd80d..6d6128ac2 100644 --- a/src/main/java/interface_adapter/logged_in/LoggedInPresenter.java +++ b/src/main/java/interface_adapter/logged_in/LoggedInPresenter.java @@ -1,19 +1,24 @@ package interface_adapter.logged_in; import interface_adapter.ViewManagerModel; +import interface_adapter.signup.SignupViewModel; +import use_case.logged_in.LoggedInOutputBoundary; /** * The Presenter for the Change Password Use Case. */ -public class LoggedInPresenter { +public class LoggedInPresenter implements LoggedInOutputBoundary { private final LoggedInViewModel loggedInViewModel; + private final SignupViewModel signupViewModel; private final ViewManagerModel viewManagerModel; public LoggedInPresenter(ViewManagerModel viewManagerModel, - LoggedInViewModel loggedInViewModel) { + LoggedInViewModel loggedInViewModel, + SignupViewModel signupViewModel) { this.viewManagerModel = viewManagerModel; this.loggedInViewModel = loggedInViewModel; + this.signupViewModel = signupViewModel; } public void prepareSuccessView(String username) { @@ -28,4 +33,10 @@ public void prepareFailView(String error) { loggedInViewModel.setState(new LoggedInState()); loggedInViewModel.firePropertyChanged(); } + + @Override + public void switchToSignUpView() { + viewManagerModel.setState(signupViewModel.getViewName()); + viewManagerModel.firePropertyChanged(); + } } diff --git a/src/main/java/use_case/logged_in/LoggedInInputBoundary.java b/src/main/java/use_case/logged_in/LoggedInInputBoundary.java new file mode 100644 index 000000000..6f0931f78 --- /dev/null +++ b/src/main/java/use_case/logged_in/LoggedInInputBoundary.java @@ -0,0 +1,11 @@ +package use_case.logged_in; + +/** + * Input Boundary for actions which are related to signing up. + */ +public interface LoggedInInputBoundary { + /** + * Executes the switch to login view use case. + */ + void switchToSignUpView(); +} diff --git a/src/main/java/use_case/logged_in/LoggedInInteractor.java b/src/main/java/use_case/logged_in/LoggedInInteractor.java new file mode 100644 index 000000000..8962538b9 --- /dev/null +++ b/src/main/java/use_case/logged_in/LoggedInInteractor.java @@ -0,0 +1,17 @@ +package use_case.logged_in; + +/** + * The Signup Interactor. + */ +public class LoggedInInteractor implements LoggedInInputBoundary { + private final LoggedInOutputBoundary userPresenter; + + public LoggedInInteractor(LoggedInOutputBoundary loggedInOutputBoundary) { + this.userPresenter = loggedInOutputBoundary; + } + + @Override + public void switchToSignUpView() { + userPresenter.switchToSignUpView(); + } +} diff --git a/src/main/java/use_case/logged_in/LoggedInOutputBoundary.java b/src/main/java/use_case/logged_in/LoggedInOutputBoundary.java new file mode 100644 index 000000000..11a7710d6 --- /dev/null +++ b/src/main/java/use_case/logged_in/LoggedInOutputBoundary.java @@ -0,0 +1,8 @@ +package use_case.logged_in; + +public interface LoggedInOutputBoundary { + /** + * Switches to the Signup View. + */ + void switchToSignUpView(); +} diff --git a/src/main/java/view/LoggedInView.java b/src/main/java/view/LoggedInView.java index de21685e1..811a03336 100644 --- a/src/main/java/view/LoggedInView.java +++ b/src/main/java/view/LoggedInView.java @@ -11,9 +11,9 @@ import javax.swing.JPanel; import interface_adapter.ViewManagerModel; +import interface_adapter.logged_in.LoggedInController; import interface_adapter.logged_in.LoggedInState; import interface_adapter.logged_in.LoggedInViewModel; -import interface_adapter.login.LoginState; import interface_adapter.showProfile.ShowProfileController; /** @@ -23,6 +23,7 @@ public class LoggedInView extends JPanel implements ActionListener, PropertyChan private final String viewName = "logged in"; private final LoggedInViewModel loggedInViewModel; + private final LoggedInController loggedInController; private final JLabel passwordErrorField = new JLabel(); private final JLabel username; @@ -33,8 +34,10 @@ public class LoggedInView extends JPanel implements ActionListener, PropertyChan private final JButton showProfile; private final ShowProfileController showProfileController; - public LoggedInView(ViewManagerModel viewManagerModel, LoggedInViewModel loggedInViewModel, + public LoggedInView(ViewManagerModel viewManagerModel, LoggedInController loggedInController, + LoggedInViewModel loggedInViewModel, ShowProfileController showProfileController) { + this.loggedInController = loggedInController; this.loggedInViewModel = loggedInViewModel; this.showProfileController = showProfileController; this.loggedInViewModel.addPropertyChangeListener(this); @@ -50,12 +53,22 @@ public LoggedInView(ViewManagerModel viewManagerModel, LoggedInViewModel loggedI buttons.add(logOut); showProfile = new JButton("Show Profile"); + buttons.add(showProfile); startChess = new JButton("Start Chess Game"); buttons.add(startChess); - buttons.add(showProfile); - logOut.addActionListener(this); +// logOut.addActionListener(this); + + logOut.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(logOut)) { + loggedInController.switchToSignUpView(); + } + } + } + ); startChess.addActionListener( evt -> { diff --git a/src/main/java/view/SignupView.java b/src/main/java/view/SignupView.java index 3ca258278..5b34c8e83 100644 --- a/src/main/java/view/SignupView.java +++ b/src/main/java/view/SignupView.java @@ -79,7 +79,9 @@ public void actionPerformed(ActionEvent evt) { toLogin.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { - signupController.switchToLoginView(); + if (evt.getSource().equals(toLogin)) { + signupController.switchToLoginView(); + } } } ); From e793da7df995b0a20980162201fdf17c59f50677 Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Sat, 30 Nov 2024 19:33:12 -0500 Subject: [PATCH 060/125] Added ; --- src/main/java/app/ShowProfileUseCaseFactory.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/app/ShowProfileUseCaseFactory.java b/src/main/java/app/ShowProfileUseCaseFactory.java index ec48b017e..319d7f9dc 100644 --- a/src/main/java/app/ShowProfileUseCaseFactory.java +++ b/src/main/java/app/ShowProfileUseCaseFactory.java @@ -48,7 +48,8 @@ public static LoggedInView create( createShowProfileUseCase(viewManagerModel, loggedInViewModel, showProfileViewModel, userDataAccessObject); - final LoggedInController loggedInController = createLoggedInUseCase(viewManagerModel, loggedInViewModel, signupViewModel) + final LoggedInController loggedInController = createLoggedInUseCase(viewManagerModel, loggedInViewModel, + signupViewModel); return new LoggedInView(viewManagerModel, loggedInController, loggedInViewModel, showProfileController); } From 08f205c4ebf37665f20b39609ebbc75af763a6d5 Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Sat, 30 Nov 2024 19:48:32 -0500 Subject: [PATCH 061/125] README.md update --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ba1d22437..d64638d00 100644 --- a/README.md +++ b/README.md @@ -58,16 +58,21 @@ To Login: Click ```Login``` to navigate to a login page, enter username and pass ### Show Profile +User can view there profile (Contain User name and rank point currently) after login by click ```Show Profile``` after login. +Note: New user's rank point is set to ```0``` -### Generate daily puzzle +### Generate daily puzzle +// TODO ### Step by step move +// TODO + ## Usage Guide This meant to me used in order of ```Signup & Login``` → ```Generate daily puzzle``` → ```Step by step move``` From b5bdb1fe0b02d9c541e76c7a90439c5a95381426 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Sat, 30 Nov 2024 23:45:55 -0500 Subject: [PATCH 062/125] Update Query view in interface adapter and create Query DAO file. --- .../data_access/QueryDataAccessObject.java | 67 +++++++++++++++++++ .../query/QueryController.java | 23 +++++++ .../query/QueryPresenter.java | 33 ++++++++- .../query/QueryProfileViewModel.java | 4 -- .../interface_adapter/query/QueryState.java | 24 +++++++ .../query/QueryViewModel.java | 24 +++++++ 6 files changed, 170 insertions(+), 5 deletions(-) create mode 100644 src/main/java/data_access/QueryDataAccessObject.java delete mode 100644 src/main/java/interface_adapter/query/QueryProfileViewModel.java create mode 100644 src/main/java/interface_adapter/query/QueryViewModel.java diff --git a/src/main/java/data_access/QueryDataAccessObject.java b/src/main/java/data_access/QueryDataAccessObject.java new file mode 100644 index 000000000..8790feeab --- /dev/null +++ b/src/main/java/data_access/QueryDataAccessObject.java @@ -0,0 +1,67 @@ +package data_access; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import use_case.daily_puzzle.PuzzleAccessException; +import use_case.query.QueryDataAccessInterface; + +import java.io.IOException; +import java.util.ArrayList; + +public class QueryDataAccessObject implements QueryDataAccessInterface { + private static final int SUCCESS_CODE = 200; + private static final String LICHESS_PUZZLE_URL = "https://lichess.org/api/puzzle/"; + private static final String DAILY_PUZZLE_URL = "daily"; + private static String PUZZLE_FROM_ID_URL; + + public ArrayList getDaily() throws PuzzleAccessException { + final OkHttpClient client = new OkHttpClient().newBuilder().build(); + final Request request = new Request.Builder().url(LICHESS_PUZZLE_URL + DAILY_PUZZLE_URL).build(); + ArrayList output = null; + + try { + final Response response = client.newCall(request).execute(); + + final JSONObject responseBody = new JSONObject(response.body().string()); + + JSONObject puzzle = responseBody.getJSONObject("puzzle"); + JSONArray solution = puzzle.getJSONArray("solution"); + output.add(puzzle.getString("id")); + for (int i = 0; i < solution.length(); i++) { + output.add(solution.getString(i)); + } + } + catch (final IOException | JSONException e) { + throw new PuzzleAccessException(e.getMessage()); + } + return output; +} + +@Override +public ArrayList fetchPuzzle(String id) throws PuzzleAccessException { + final OkHttpClient client = new OkHttpClient().newBuilder().build(); + final Request request = new Request.Builder().url(LICHESS_PUZZLE_URL + PUZZLE_FROM_ID_URL).build(); + ArrayList output = null; + + try { + final Response response = client.newCall(request).execute(); + + final JSONObject responseBody = new JSONObject(response.body().string()); + + JSONArray solution = responseBody.getJSONArray("solution"); + output.add(responseBody.getJSONObject("game").getString("pgn")); + for (int i = 0; i < solution.length(); i++) { + output.add(solution.getString(i)); + } + } + catch (final IOException | JSONException e) { + throw new PuzzleAccessException(e.getMessage()); + } + return output; +} +} +} diff --git a/src/main/java/interface_adapter/query/QueryController.java b/src/main/java/interface_adapter/query/QueryController.java index 5fa449029..333a60596 100644 --- a/src/main/java/interface_adapter/query/QueryController.java +++ b/src/main/java/interface_adapter/query/QueryController.java @@ -1,4 +1,27 @@ package interface_adapter.query; +import use_case.query.QueryInputBoundary; +import use_case.query.QueryInputData; + +/** + * The controller for the ShowProfile use case. + */ public class QueryController { + + private final QueryInputBoundary QueryInputInteractor; + + public QueryController(QueryInputBoundary QueryInteractor) { + this.QueryInputInteractor = QueryInteractor; + } + + /** + * Execute the showProfile use case. + * @param username the username of the user logging in + */ + public void execute(String username) { + final QueryInputData queryInputData = new QueryInputData(username); + + QueryInputInteractor.execute(queryInputData); + } } + diff --git a/src/main/java/interface_adapter/query/QueryPresenter.java b/src/main/java/interface_adapter/query/QueryPresenter.java index 14b19dada..b9c4c8dc7 100644 --- a/src/main/java/interface_adapter/query/QueryPresenter.java +++ b/src/main/java/interface_adapter/query/QueryPresenter.java @@ -1,4 +1,35 @@ package interface_adapter.query; -public class QueryPresenter { +import interface_adapter.ViewManagerModel; +import use_case.query.QueryOutputBoundary; +import use_case.query.QueryOutputData; +import view.ViewManager; + +public class QueryPresenter implements QueryOutputBoundary { + + private final QueryViewModel queryViewModel; + private final ViewManagerModel viewManagerModel; + + public QueryPresenter(QueryViewModel queryViewModel, ViewManagerModel viewManagerModel) { + this.queryViewModel = queryViewModel; + this.viewManagerModel = viewManagerModel; + } + + @Override + public void prepareSuccessView(QueryOutputData outputData) { + // On success, switch to the Profile view. + + final QueryState queryState = queryViewModel.getState(); + queryState.setUsername(outputData.getUsername()); + this.queryViewModel.setState(queryState); + this.queryViewModel.firePropertyChanged(); + + this.viewManagerModel.setState(queryViewModel.getViewName()); + this.viewManagerModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String errorMessage) { + + } } diff --git a/src/main/java/interface_adapter/query/QueryProfileViewModel.java b/src/main/java/interface_adapter/query/QueryProfileViewModel.java deleted file mode 100644 index 0673fc325..000000000 --- a/src/main/java/interface_adapter/query/QueryProfileViewModel.java +++ /dev/null @@ -1,4 +0,0 @@ -package interface_adapter.query; - -public class QueryProfileViewModel { -} diff --git a/src/main/java/interface_adapter/query/QueryState.java b/src/main/java/interface_adapter/query/QueryState.java index bd9021aa8..5bb4d40e6 100644 --- a/src/main/java/interface_adapter/query/QueryState.java +++ b/src/main/java/interface_adapter/query/QueryState.java @@ -1,4 +1,28 @@ package interface_adapter.query; +import java.util.ArrayList; +import java.util.Dictionary; +import java.util.List; + +/** + * The State information representing the logged-in user. + */ public class QueryState { + private String username = ""; + + public QueryState() { + + } + + public void setUsername(String username) { + this.username = username; + } + + public String getUsername() { + return username; + } + + public ArrayList getRankHistory() { + return rankHistory; + } } diff --git a/src/main/java/interface_adapter/query/QueryViewModel.java b/src/main/java/interface_adapter/query/QueryViewModel.java new file mode 100644 index 000000000..a0695bef6 --- /dev/null +++ b/src/main/java/interface_adapter/query/QueryViewModel.java @@ -0,0 +1,24 @@ +package interface_adapter.query; + +import interface_adapter.ViewModel; + +import java.util.ArrayList; + +/** + * The View Model for the query view. + */ +public class QueryViewModel extends ViewModel { + + public QueryViewModel() { + super("Query"); + setState(new QueryState()); + } + + public String getUsername() { + return getState().getUsername(); + } + + public ArrayList getRankHistory() { + return getState().getRankHistory(); + } +} From 4009401a6cdd0de524a58da36346c57dec4d20bf Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Sun, 1 Dec 2024 00:27:21 -0500 Subject: [PATCH 063/125] Added use case output data. --- .../java/use_case/query/QueryOutputData.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/main/java/use_case/query/QueryOutputData.java diff --git a/src/main/java/use_case/query/QueryOutputData.java b/src/main/java/use_case/query/QueryOutputData.java new file mode 100644 index 000000000..1f2efae76 --- /dev/null +++ b/src/main/java/use_case/query/QueryOutputData.java @@ -0,0 +1,28 @@ +package use_case.query; + +import java.util.ArrayList; + +/** + * Output Data for the ShowProfile Use case. + */ +public class QueryOutputData { + + private final String username; + private final ArrayList RankHistory; + private final boolean useCaseSucceeded; + + public QueryOutputData(String username, ArrayList RankHistory, boolean useCaseSucceeded) { + this.username = username; + this.RankHistory = RankHistory; + this.useCaseSucceeded = useCaseSucceeded; + } + + public int getRankHistory() { + return RankHistory; + } + + public String getUsername() { + return username; + } + +} From 256c9c395734e4cddeef70ec69b2d7aa09b81dca Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Sun, 1 Dec 2024 00:28:38 -0500 Subject: [PATCH 064/125] Added use case output data. --- src/main/java/use_case/query/QueryOutputData.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/use_case/query/QueryOutputData.java b/src/main/java/use_case/query/QueryOutputData.java index 1f2efae76..a5d39eaac 100644 --- a/src/main/java/use_case/query/QueryOutputData.java +++ b/src/main/java/use_case/query/QueryOutputData.java @@ -8,17 +8,17 @@ public class QueryOutputData { private final String username; - private final ArrayList RankHistory; + private final ArrayList rankHistory; private final boolean useCaseSucceeded; - public QueryOutputData(String username, ArrayList RankHistory, boolean useCaseSucceeded) { + public QueryOutputData(String username, ArrayList rankHistory, boolean useCaseSucceeded) { this.username = username; - this.RankHistory = RankHistory; + this.rankHistory = rankHistory; this.useCaseSucceeded = useCaseSucceeded; } - public int getRankHistory() { - return RankHistory; + public ArrayList getRankHistory() { + return rankHistory; } public String getUsername() { From d9f74dae95d422e8fc02e363ddd129d038404400 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Mon, 2 Dec 2024 08:11:35 -0500 Subject: [PATCH 065/125] Update pom file and added RankHistory Entity. --- pom.xml | 5 + .../data_access/QueryDataAccessObject.java | 99 +++++++++---------- src/main/java/entity/RankHistory.java | 64 ++++++++++++ .../query/QueryController.java | 16 ++- .../query/QueryPresenter.java | 23 +++-- .../interface_adapter/query/QueryState.java | 20 ++-- .../query/QueryViewModel.java | 12 +-- 7 files changed, 149 insertions(+), 90 deletions(-) create mode 100644 src/main/java/entity/RankHistory.java diff --git a/pom.xml b/pom.xml index 428273a2a..8f715e7bf 100644 --- a/pom.xml +++ b/pom.xml @@ -32,6 +32,11 @@ chariot 0.1.10 + + com.alibaba + fastjson + 1.2.79 + diff --git a/src/main/java/data_access/QueryDataAccessObject.java b/src/main/java/data_access/QueryDataAccessObject.java index 8790feeab..4fc45c3bf 100644 --- a/src/main/java/data_access/QueryDataAccessObject.java +++ b/src/main/java/data_access/QueryDataAccessObject.java @@ -1,67 +1,60 @@ package data_access; +import java.io.IOException; + +import entity.RankHistory; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import use_case.daily_puzzle.PuzzleAccessException; import use_case.query.QueryDataAccessInterface; -import java.io.IOException; -import java.util.ArrayList; - +/** + * The DAO for accessing user rank history stored in the database. + */ public class QueryDataAccessObject implements QueryDataAccessInterface { - private static final int SUCCESS_CODE = 200; - private static final String LICHESS_PUZZLE_URL = "https://lichess.org/api/puzzle/"; - private static final String DAILY_PUZZLE_URL = "daily"; - private static String PUZZLE_FROM_ID_URL; + @Override + public RankHistory showRankHistory(String username) { - public ArrayList getDaily() throws PuzzleAccessException { - final OkHttpClient client = new OkHttpClient().newBuilder().build(); - final Request request = new Request.Builder().url(LICHESS_PUZZLE_URL + DAILY_PUZZLE_URL).build(); - ArrayList output = null; + final RankHistory rankHistory = new RankHistory(); - try { - final Response response = client.newCall(request).execute(); - - final JSONObject responseBody = new JSONObject(response.body().string()); - - JSONObject puzzle = responseBody.getJSONObject("puzzle"); - JSONArray solution = puzzle.getJSONArray("solution"); - output.add(puzzle.getString("id")); - for (int i = 0; i < solution.length(); i++) { - output.add(solution.getString(i)); + final String url = String.format("https://lichess.org/api/user/%s/rating-history", username); + final OkHttpClient client = new OkHttpClient().newBuilder().build(); + final Request request = new Request.Builder() + .url(url) + .build(); + + try (Response response = client.newCall(request).execute()) { + + final String responseBody = response.body().string(); + final com.alibaba.fastjson.JSONArray jsonArray = com.alibaba.fastjson.JSONArray.parseArray(responseBody); + + jsonArray.stream().forEach(str -> { + final com.alibaba.fastjson.JSONObject jsonObject = + com.alibaba.fastjson.JSONObject.parseObject(str.toString()); + + final String name = (String) jsonObject.get("name"); + if ("Puzzles".equals(name)) { + final Object points = jsonObject.get("points"); + final com.alibaba.fastjson.JSONArray pointarr = + com.alibaba.fastjson.JSONArray.parseArray(points.toString()); + + final Object[] objects = pointarr.toArray(); + + for (Object object : objects) { + final com.alibaba.fastjson.JSONArray ranks = + com.alibaba.fastjson.JSONArray.parseArray(object.toString()); + final int year = (Integer) ranks.get(0); + final int month = (Integer) ranks.get(1); + final int day = (Integer) ranks.get(2); + final int rank = (Integer) ranks.get(3); + rankHistory.addRankHistory(year, month, day, rank); + } + } + }); + return rankHistory; } - } - catch (final IOException | JSONException e) { - throw new PuzzleAccessException(e.getMessage()); - } - return output; -} - -@Override -public ArrayList fetchPuzzle(String id) throws PuzzleAccessException { - final OkHttpClient client = new OkHttpClient().newBuilder().build(); - final Request request = new Request.Builder().url(LICHESS_PUZZLE_URL + PUZZLE_FROM_ID_URL).build(); - ArrayList output = null; - - try { - final Response response = client.newCall(request).execute(); - - final JSONObject responseBody = new JSONObject(response.body().string()); - - JSONArray solution = responseBody.getJSONArray("solution"); - output.add(responseBody.getJSONObject("game").getString("pgn")); - for (int i = 0; i < solution.length(); i++) { - output.add(solution.getString(i)); + catch (IOException ex) { + throw new RuntimeException(ex); } } - catch (final IOException | JSONException e) { - throw new PuzzleAccessException(e.getMessage()); - } - return output; -} -} } diff --git a/src/main/java/entity/RankHistory.java b/src/main/java/entity/RankHistory.java new file mode 100644 index 000000000..e13cd9842 --- /dev/null +++ b/src/main/java/entity/RankHistory.java @@ -0,0 +1,64 @@ +package entity; + +import java.util.ArrayList; +import java.util.List; + +/** + * The representation of user rank history for our program. + */ + +public class RankHistory { + private final List rankHistoryList; + + public RankHistory() { + this.rankHistoryList = new ArrayList<>(); + } + + public List getRanks() { + return rankHistoryList; + } + + /** + * Print the RankHistory. + */ + public void printRankHistory() { + for (Rank rank : rankHistoryList) { + System.out.println(rank); + } + } + + /** + * Add user rank for our program. + * @param year the rank year. + * @param month the rank month. + * @param day the rank day. + * @param rank the rank . + */ + public void addRankHistory(int year, int month, int day, int rank) { + final Rank rh = new Rank(year, month, day, rank); + this.rankHistoryList.add(rh); + } + + /** + * The representation of user rank for our program. + */ + public static class Rank { + private final int year; + private final int month; + private final int day; + private final int rank; + + public Rank(int year, int month, int day, int rank) { + this.year = year; + this.month = month + 1; + this.day = day; + this.rank = rank; + } + + @Override + public String toString() { + return "Year:" + year + " Month:" + month + + " Day:" + day + " Rank:" + rank; + } + } +} diff --git a/src/main/java/interface_adapter/query/QueryController.java b/src/main/java/interface_adapter/query/QueryController.java index 333a60596..8bb2cadd6 100644 --- a/src/main/java/interface_adapter/query/QueryController.java +++ b/src/main/java/interface_adapter/query/QueryController.java @@ -1,27 +1,23 @@ package interface_adapter.query; import use_case.query.QueryInputBoundary; -import use_case.query.QueryInputData; /** - * The controller for the ShowProfile use case. + * The controller for the query use case. */ public class QueryController { - private final QueryInputBoundary QueryInputInteractor; + private final QueryInputBoundary queryInteractor; - public QueryController(QueryInputBoundary QueryInteractor) { - this.QueryInputInteractor = QueryInteractor; + public QueryController(QueryInputBoundary queryInteractor) { + this.queryInteractor = queryInteractor; } /** - * Execute the showProfile use case. + * Execute the query use case. * @param username the username of the user logging in */ public void execute(String username) { - final QueryInputData queryInputData = new QueryInputData(username); - - QueryInputInteractor.execute(queryInputData); + queryInteractor.execute(username); } } - diff --git a/src/main/java/interface_adapter/query/QueryPresenter.java b/src/main/java/interface_adapter/query/QueryPresenter.java index b9c4c8dc7..aa5b152a4 100644 --- a/src/main/java/interface_adapter/query/QueryPresenter.java +++ b/src/main/java/interface_adapter/query/QueryPresenter.java @@ -1,10 +1,12 @@ package interface_adapter.query; +import entity.RankHistory; import interface_adapter.ViewManagerModel; import use_case.query.QueryOutputBoundary; -import use_case.query.QueryOutputData; -import view.ViewManager; +/** + * The presenter for query viewing. + */ public class QueryPresenter implements QueryOutputBoundary { private final QueryViewModel queryViewModel; @@ -15,12 +17,16 @@ public QueryPresenter(QueryViewModel queryViewModel, ViewManagerModel viewManage this.viewManagerModel = viewManagerModel; } + /** + * Prepares the success view for the query related Use Cases. + * + * @param rankHistoryList the user rank history data. + */ @Override - public void prepareSuccessView(QueryOutputData outputData) { - // On success, switch to the Profile view. - + public void prepareSuccessView(RankHistory rankHistoryList) { + // On success, switch to the Query view. final QueryState queryState = queryViewModel.getState(); - queryState.setUsername(outputData.getUsername()); + queryState.setRankHistoryList(rankHistoryList); this.queryViewModel.setState(queryState); this.queryViewModel.firePropertyChanged(); @@ -28,6 +34,11 @@ public void prepareSuccessView(QueryOutputData outputData) { this.viewManagerModel.firePropertyChanged(); } + /** + * Prepares the failure view for the query related Use Cases. + * + * @param errorMessage the explanation of the failure + */ @Override public void prepareFailView(String errorMessage) { diff --git a/src/main/java/interface_adapter/query/QueryState.java b/src/main/java/interface_adapter/query/QueryState.java index 5bb4d40e6..66ce0bef6 100644 --- a/src/main/java/interface_adapter/query/QueryState.java +++ b/src/main/java/interface_adapter/query/QueryState.java @@ -1,28 +1,22 @@ package interface_adapter.query; -import java.util.ArrayList; -import java.util.Dictionary; -import java.util.List; +import entity.RankHistory; /** - * The State information representing the logged-in user. + * The State information representing the query user. */ public class QueryState { - private String username = ""; + private RankHistory rankHistoryList; public QueryState() { } - public void setUsername(String username) { - this.username = username; + public void setRankHistoryList(RankHistory rankHistoryList) { + this.rankHistoryList = rankHistoryList; } - public String getUsername() { - return username; - } - - public ArrayList getRankHistory() { - return rankHistory; + public RankHistory getRankHistoryList() { + return rankHistoryList; } } diff --git a/src/main/java/interface_adapter/query/QueryViewModel.java b/src/main/java/interface_adapter/query/QueryViewModel.java index a0695bef6..54c56cff8 100644 --- a/src/main/java/interface_adapter/query/QueryViewModel.java +++ b/src/main/java/interface_adapter/query/QueryViewModel.java @@ -1,24 +1,20 @@ package interface_adapter.query; +import entity.RankHistory; import interface_adapter.ViewModel; -import java.util.ArrayList; - /** * The View Model for the query view. */ public class QueryViewModel extends ViewModel { public QueryViewModel() { - super("Query"); + super("query"); setState(new QueryState()); } - public String getUsername() { - return getState().getUsername(); + public RankHistory getRankHistoryList() { + return getState().getRankHistoryList(); } - public ArrayList getRankHistory() { - return getState().getRankHistory(); - } } From c2d0abcc2fd763c8728f6bf0b77535e3e737145f Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Mon, 2 Dec 2024 08:25:05 -0500 Subject: [PATCH 066/125] Update use cases and query view. --- .../data_access/QueryDataAccessObject.java | 3 +- .../query/QueryController.java | 2 - .../query/QueryPresenter.java | 3 +- .../use_case/query/DataAccessException.java | 10 +++ .../query/QueryDataAccessInterface.java | 12 ++++ .../use_case/query/QueryInputBoundary.java | 13 ++-- .../java/use_case/query/QueryInputData.java | 15 ----- .../java/use_case/query/QueryInteractor.java | 26 +++++++- .../use_case/query/QueryOutputBoundary.java | 16 +++++ .../java/use_case/query/QueryOutputData.java | 28 -------- src/main/java/view/QueryView.java | 64 +++++++++++++++++++ 11 files changed, 133 insertions(+), 59 deletions(-) create mode 100644 src/main/java/use_case/query/DataAccessException.java delete mode 100644 src/main/java/use_case/query/QueryInputData.java delete mode 100644 src/main/java/use_case/query/QueryOutputData.java create mode 100644 src/main/java/view/QueryView.java diff --git a/src/main/java/data_access/QueryDataAccessObject.java b/src/main/java/data_access/QueryDataAccessObject.java index 4fc45c3bf..f52edd2c0 100644 --- a/src/main/java/data_access/QueryDataAccessObject.java +++ b/src/main/java/data_access/QueryDataAccessObject.java @@ -6,12 +6,11 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import use_case.query.QueryDataAccessInterface; /** * The DAO for accessing user rank history stored in the database. */ -public class QueryDataAccessObject implements QueryDataAccessInterface { +public class QueryDataAccessObject { @Override public RankHistory showRankHistory(String username) { diff --git a/src/main/java/interface_adapter/query/QueryController.java b/src/main/java/interface_adapter/query/QueryController.java index 8bb2cadd6..2af47a403 100644 --- a/src/main/java/interface_adapter/query/QueryController.java +++ b/src/main/java/interface_adapter/query/QueryController.java @@ -1,7 +1,5 @@ package interface_adapter.query; -import use_case.query.QueryInputBoundary; - /** * The controller for the query use case. */ diff --git a/src/main/java/interface_adapter/query/QueryPresenter.java b/src/main/java/interface_adapter/query/QueryPresenter.java index aa5b152a4..746b6a42d 100644 --- a/src/main/java/interface_adapter/query/QueryPresenter.java +++ b/src/main/java/interface_adapter/query/QueryPresenter.java @@ -2,12 +2,11 @@ import entity.RankHistory; import interface_adapter.ViewManagerModel; -import use_case.query.QueryOutputBoundary; /** * The presenter for query viewing. */ -public class QueryPresenter implements QueryOutputBoundary { +public class QueryPresenter { private final QueryViewModel queryViewModel; private final ViewManagerModel viewManagerModel; diff --git a/src/main/java/use_case/query/DataAccessException.java b/src/main/java/use_case/query/DataAccessException.java new file mode 100644 index 000000000..a70b2edfb --- /dev/null +++ b/src/main/java/use_case/query/DataAccessException.java @@ -0,0 +1,10 @@ +package use_case.query; + +/** + * Exception thrown when there is an error with accessing data. + */ +public class DataAccessException extends Exception { + public DataAccessException(String string) { + super(string); + } +} diff --git a/src/main/java/use_case/query/QueryDataAccessInterface.java b/src/main/java/use_case/query/QueryDataAccessInterface.java index dc6ec1f12..cee7dad35 100644 --- a/src/main/java/use_case/query/QueryDataAccessInterface.java +++ b/src/main/java/use_case/query/QueryDataAccessInterface.java @@ -1,4 +1,16 @@ package use_case.query; +import entity.RankHistory; + +/** + * Interface for the QueryDAO. + */ public interface QueryDataAccessInterface { + + /** + * Saves a rank history for a given user. + * @param username the query user's name. + * @return the rank history of the user. + */ + RankHistory showRankHistory(String username); } diff --git a/src/main/java/use_case/query/QueryInputBoundary.java b/src/main/java/use_case/query/QueryInputBoundary.java index 743cc81ea..2a75ad8dd 100644 --- a/src/main/java/use_case/query/QueryInputBoundary.java +++ b/src/main/java/use_case/query/QueryInputBoundary.java @@ -1,18 +1,13 @@ package use_case.query; /** - * Input Boundary for actions which are related to searching user. + * The Input Boundary for query use cases. */ public interface QueryInputBoundary { /** - * Executes the search User use case. - * @param username the input data + * Executes the query use case. + * @param username the user . */ void execute(String username); - - /** - * Executes the switch to login view use case. - */ - void switchToLoginView(); -} \ No newline at end of file +} diff --git a/src/main/java/use_case/query/QueryInputData.java b/src/main/java/use_case/query/QueryInputData.java deleted file mode 100644 index 69b1f8694..000000000 --- a/src/main/java/use_case/query/QueryInputData.java +++ /dev/null @@ -1,15 +0,0 @@ -package use_case.query; - -/** - * The Input Data for the SearchUser use case. - */ - -public class QueryInputData { - private final String username; - - public QueryInputData(String username) { - this.username = username; } - - public String getUsername() { - return username; } -} diff --git a/src/main/java/use_case/query/QueryInteractor.java b/src/main/java/use_case/query/QueryInteractor.java index dd3bea5eb..da198fed1 100644 --- a/src/main/java/use_case/query/QueryInteractor.java +++ b/src/main/java/use_case/query/QueryInteractor.java @@ -1,4 +1,28 @@ package use_case.query; -public class QueryInteractor { +import entity.RankHistory; + +/** + * The Query Interactor. + */ +public class QueryInteractor implements QueryInputBoundary { + private final QueryDataAccessInterface queryDataAccessInterface; + private final QueryOutputBoundary queryOutputBoundary; + + public QueryInteractor(QueryDataAccessInterface queryDataAccessInterface, + QueryOutputBoundary queryOutputBoundary) { + this.queryDataAccessInterface = queryDataAccessInterface; + this.queryOutputBoundary = queryOutputBoundary; + } + + /** + * Executes the query use case. + * + * @param username the user. + */ + @Override + public void execute(String username) { + final RankHistory rankHistoryList = queryDataAccessInterface.showRankHistory(username); + queryOutputBoundary.prepareSuccessView(rankHistoryList); + } } diff --git a/src/main/java/use_case/query/QueryOutputBoundary.java b/src/main/java/use_case/query/QueryOutputBoundary.java index aad4accd5..3de9ac93a 100644 --- a/src/main/java/use_case/query/QueryOutputBoundary.java +++ b/src/main/java/use_case/query/QueryOutputBoundary.java @@ -1,4 +1,20 @@ package use_case.query; +import entity.RankHistory; + +/** + * The output boundary for the query Use Case. + */ public interface QueryOutputBoundary { + /** + * Prepares the success view for the query related Use Cases. + * @param rankHistoryList the rank history data. + */ + void prepareSuccessView(RankHistory rankHistoryList); + + /** + * Prepares the failure view for the query related Use Cases. + * @param errorMessage the explanation of the failure + */ + void prepareFailView(String errorMessage); } diff --git a/src/main/java/use_case/query/QueryOutputData.java b/src/main/java/use_case/query/QueryOutputData.java deleted file mode 100644 index a5d39eaac..000000000 --- a/src/main/java/use_case/query/QueryOutputData.java +++ /dev/null @@ -1,28 +0,0 @@ -package use_case.query; - -import java.util.ArrayList; - -/** - * Output Data for the ShowProfile Use case. - */ -public class QueryOutputData { - - private final String username; - private final ArrayList rankHistory; - private final boolean useCaseSucceeded; - - public QueryOutputData(String username, ArrayList rankHistory, boolean useCaseSucceeded) { - this.username = username; - this.rankHistory = rankHistory; - this.useCaseSucceeded = useCaseSucceeded; - } - - public ArrayList getRankHistory() { - return rankHistory; - } - - public String getUsername() { - return username; - } - -} diff --git a/src/main/java/view/QueryView.java b/src/main/java/view/QueryView.java new file mode 100644 index 000000000..0a9fb5b62 --- /dev/null +++ b/src/main/java/view/QueryView.java @@ -0,0 +1,64 @@ +package view; + +import entity.RankHistory; +import interface_adapter.ViewManagerModel; +import interface_adapter.query.QueryViewModel; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/** + * The view of user profile. + */ +public class QueryView extends JPanel implements ActionListener, PropertyChangeListener { + + private final String viewName = "query"; + private final QueryViewModel queryViewModel; + private final JPanel contentPanel; + + public QueryView(ViewManagerModel viewManagerModel, QueryViewModel queryViewModel) { + this.queryViewModel = queryViewModel; + this.queryViewModel.addPropertyChangeListener(this); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + final JLabel title = new JLabel("Rank History"); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + + final JScrollPane scrollPane = new JScrollPane(); + + contentPanel = new JPanel(); + contentPanel.setLayout(new GridLayout(0, 1)); + + scrollPane.setViewportView(contentPanel); + + this.add(title); + this.add(scrollPane); + + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + final RankHistory rankHistory = queryViewModel.getRankHistoryList(); + for (int i = 0; i < rankHistory.getRanks().size(); i++) { + contentPanel.add(new JLabel(rankHistory.getRanks().get(i).toString())); + } + } + + /** + * React to a button click that results in evt. + * @param evt the ActionEvent to react to + */ + public void actionPerformed(ActionEvent evt) { + + } + + public String getViewName() { + return viewName; + } + +} From ce84ec01caa235b4a93405e4a454f94f1a4b8bea Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Mon, 2 Dec 2024 09:06:08 -0500 Subject: [PATCH 067/125] Update main_ck with query view. --- src/main/java/app/Main_ck.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/app/Main_ck.java b/src/main/java/app/Main_ck.java index 8ab77e476..f59cd1aa2 100644 --- a/src/main/java/app/Main_ck.java +++ b/src/main/java/app/Main_ck.java @@ -8,11 +8,13 @@ import data_access.ChessDataAccessObject; import data_access.UserDataAccessObject; +import data_access.QueryDataAccessObject; import interface_adapter.ViewManagerModel; import interface_adapter.logged_in.LoggedInViewModel; import interface_adapter.login.LoginViewModel; import interface_adapter.showProfile.ShowProfileViewModel; import interface_adapter.signup.SignupViewModel; +import interface_adapter.query.QueryViewModel; import view.*; /** @@ -40,8 +42,10 @@ public static void main(String[] args) { final LoggedInViewModel loggedInViewModel = new LoggedInViewModel(); final SignupViewModel signupViewModel = new SignupViewModel(); final ShowProfileViewModel showProfileViewModel = new ShowProfileViewModel(); + final QueryViewModel queryViewModel = new QueryViewModel(); final UserDataAccessObject userDataAccessObject = new UserDataAccessObject(); + final QueryDataAccessObject queryDataAccessObject = new QueryDataAccessObject(); final SignupView signupView = SignupApp.create(viewManagerModel, loginViewModel, signupViewModel, userDataAccessObject); final LoginView loginView = LoginApp.create(viewManagerModel, loginViewModel, @@ -50,11 +54,13 @@ public static void main(String[] args) { showProfileViewModel, userDataAccessObject); final ProfileView profileView = new ProfileView(viewManagerModel, showProfileViewModel); // final LoggedInView loggedInView = new LoggedInView(viewManagerModel, loggedInViewModel); + final QueryView queryView = new QueryView(viewManagerModel, queryViewModel); views.add(signupView, signupView.getViewName()); views.add(loginView, loginView.getViewName()); views.add(loggedInView, loggedInView.getViewName()); views.add(profileView, profileView.getViewName()); + views.add(queryView, queryView.getViewName()); final CK_ChessAppBuilder chessAppBuilder = new CK_ChessAppBuilder(); chessAppBuilder.addChessDAO(new ChessDataAccessObject()) From 9f2197ab6edfeefc9d603d6c36a68614f6d818a6 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Mon, 2 Dec 2024 10:00:57 -0500 Subject: [PATCH 068/125] Update LoggedInView.java and ShowProfileUseCaseFactory.java with query view. --- .../java/app/ShowProfileUseCaseFactory.java | 20 +++++++++++++++++-- src/main/java/view/LoggedInView.java | 7 +++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/main/java/app/ShowProfileUseCaseFactory.java b/src/main/java/app/ShowProfileUseCaseFactory.java index 8d62b8ddb..339bd2bff 100644 --- a/src/main/java/app/ShowProfileUseCaseFactory.java +++ b/src/main/java/app/ShowProfileUseCaseFactory.java @@ -5,10 +5,18 @@ import interface_adapter.showProfile.ShowProfileController; import interface_adapter.showProfile.ShowProfilePresenter; import interface_adapter.showProfile.ShowProfileViewModel; +import interface_adapter.query.QueryController; +import interface_adapter.query.QueryPresenter; +import interface_adapter.query.QueryViewModel; import use_case.showProfile.ShowProfileInputBoundary; import use_case.showProfile.ShowProfileInteractor; import use_case.showProfile.ShowProfileOutputBoundary; import use_case.showProfile.ShowProfileUserDataAccessInterface; +import use_case.query.QueryDataAccessInterface; +import use_case.query.QueryInputBoundary; +import use_case.query.QueryInteractor; +import use_case.query.QueryOutputBoundary; + import view.LoggedInView; /** @@ -28,19 +36,27 @@ private ShowProfileUseCaseFactory() { * @param loggedInViewModel the loggedInViewModel to inject into the LoggedInView * @param showProfileViewModel * @param userDataAccessObject the ChangePasswordUserDataAccessInterface to inject into the LoggedInView + * @param queryViewModel the QueryViewModel to inject into the LoggedInView + * @param queryDataAccessObject the Query DataAccessObject * @return the LoggedInView created for the provided input classes */ public static LoggedInView create( ViewManagerModel viewManagerModel, LoggedInViewModel loggedInViewModel, ShowProfileViewModel showProfileViewModel, - ShowProfileUserDataAccessInterface userDataAccessObject) { + QueryViewModel queryViewModel, + ShowProfileUserDataAccessInterface userDataAccessObject, + QueryDataAccessInterface queryDataAccessObject) { final ShowProfileController showProfileController = createShowProfileUseCase(viewManagerModel, loggedInViewModel, showProfileViewModel, userDataAccessObject); - return new LoggedInView(viewManagerModel, loggedInViewModel, showProfileController); + final QueryOutputBoundary queryOutputBoundary = new QueryPresenter(queryViewModel, viewManagerModel); + final QueryInputBoundary queryInputInteractor = new QueryInteractor(queryDataAccessObject, queryOutputBoundary); + final QueryController queryController = new QueryController(queryInputInteractor); + + return new LoggedInView(viewManagerModel, loggedInViewModel, showProfileController, queryController); } diff --git a/src/main/java/view/LoggedInView.java b/src/main/java/view/LoggedInView.java index c4a7cdc6c..651ebdb44 100644 --- a/src/main/java/view/LoggedInView.java +++ b/src/main/java/view/LoggedInView.java @@ -15,7 +15,6 @@ import interface_adapter.ViewManagerModel; import interface_adapter.logged_in.LoggedInState; import interface_adapter.logged_in.LoggedInViewModel; -import interface_adapter.login.LoginState; import interface_adapter.query.QueryController; import interface_adapter.showProfile.ShowProfileController; @@ -39,7 +38,7 @@ public class LoggedInView extends JPanel implements ActionListener, PropertyChan private final ShowProfileController showProfileController; public LoggedInView(ViewManagerModel viewManagerModel, LoggedInViewModel loggedInViewModel, - ShowProfileController showProfileController) { + ShowProfileController showProfileController, QueryController queryController) { this.loggedInViewModel = loggedInViewModel; this.showProfileController = showProfileController; this.loggedInViewModel.addPropertyChangeListener(this); @@ -101,11 +100,11 @@ public void actionPerformed(ActionEvent evt) { QueryController.execute( currentState.getUsername() - ) + ); } } } - ) + ); this.add(title); this.add(usernameInfo); From b59f1282f7d665a1b52ed21d1146286cf4173e4c Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Mon, 2 Dec 2024 11:35:37 -0500 Subject: [PATCH 069/125] Fixing bugs. --- src/main/java/app/Main_ck.java | 2 +- .../java/app/ShowProfileUseCaseFactory.java | 19 ++++++++++--------- .../data_access/QueryDataAccessObject.java | 3 ++- .../query/QueryController.java | 2 ++ .../query/QueryPresenter.java | 3 ++- src/main/java/view/LoggedInView.java | 2 +- 6 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/main/java/app/Main_ck.java b/src/main/java/app/Main_ck.java index f59cd1aa2..b16c3e043 100644 --- a/src/main/java/app/Main_ck.java +++ b/src/main/java/app/Main_ck.java @@ -51,7 +51,7 @@ public static void main(String[] args) { final LoginView loginView = LoginApp.create(viewManagerModel, loginViewModel, loggedInViewModel, userDataAccessObject); final LoggedInView loggedInView = ShowProfileUseCaseFactory.create(viewManagerModel, loggedInViewModel, - showProfileViewModel, userDataAccessObject); + showProfileViewModel, queryViewModel, userDataAccessObject, queryDataAccessObject); final ProfileView profileView = new ProfileView(viewManagerModel, showProfileViewModel); // final LoggedInView loggedInView = new LoggedInView(viewManagerModel, loggedInViewModel); final QueryView queryView = new QueryView(viewManagerModel, queryViewModel); diff --git a/src/main/java/app/ShowProfileUseCaseFactory.java b/src/main/java/app/ShowProfileUseCaseFactory.java index 339bd2bff..406b6b31c 100644 --- a/src/main/java/app/ShowProfileUseCaseFactory.java +++ b/src/main/java/app/ShowProfileUseCaseFactory.java @@ -2,23 +2,24 @@ import interface_adapter.ViewManagerModel; import interface_adapter.logged_in.LoggedInViewModel; -import interface_adapter.showProfile.ShowProfileController; -import interface_adapter.showProfile.ShowProfilePresenter; -import interface_adapter.showProfile.ShowProfileViewModel; import interface_adapter.query.QueryController; import interface_adapter.query.QueryPresenter; import interface_adapter.query.QueryViewModel; -import use_case.showProfile.ShowProfileInputBoundary; -import use_case.showProfile.ShowProfileInteractor; -import use_case.showProfile.ShowProfileOutputBoundary; -import use_case.showProfile.ShowProfileUserDataAccessInterface; +import interface_adapter.showProfile.ShowProfileController; +import interface_adapter.showProfile.ShowProfilePresenter; +import interface_adapter.showProfile.ShowProfileViewModel; import use_case.query.QueryDataAccessInterface; import use_case.query.QueryInputBoundary; import use_case.query.QueryInteractor; import use_case.query.QueryOutputBoundary; - +import use_case.showProfile.ShowProfileInputBoundary; +import use_case.showProfile.ShowProfileInteractor; +import use_case.showProfile.ShowProfileOutputBoundary; +import use_case.showProfile.ShowProfileUserDataAccessInterface; import view.LoggedInView; +import javax.management.Query; + /** * This class contains the static factory function for creating the LoggedInView. */ @@ -34,7 +35,7 @@ private ShowProfileUseCaseFactory() { * * @param viewManagerModel the ViewManagerModel to inject into the LoggedInView * @param loggedInViewModel the loggedInViewModel to inject into the LoggedInView - * @param showProfileViewModel + * @param showProfileViewModel fsf * @param userDataAccessObject the ChangePasswordUserDataAccessInterface to inject into the LoggedInView * @param queryViewModel the QueryViewModel to inject into the LoggedInView * @param queryDataAccessObject the Query DataAccessObject diff --git a/src/main/java/data_access/QueryDataAccessObject.java b/src/main/java/data_access/QueryDataAccessObject.java index f52edd2c0..4fc45c3bf 100644 --- a/src/main/java/data_access/QueryDataAccessObject.java +++ b/src/main/java/data_access/QueryDataAccessObject.java @@ -6,11 +6,12 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; +import use_case.query.QueryDataAccessInterface; /** * The DAO for accessing user rank history stored in the database. */ -public class QueryDataAccessObject { +public class QueryDataAccessObject implements QueryDataAccessInterface { @Override public RankHistory showRankHistory(String username) { diff --git a/src/main/java/interface_adapter/query/QueryController.java b/src/main/java/interface_adapter/query/QueryController.java index 2af47a403..8bb2cadd6 100644 --- a/src/main/java/interface_adapter/query/QueryController.java +++ b/src/main/java/interface_adapter/query/QueryController.java @@ -1,5 +1,7 @@ package interface_adapter.query; +import use_case.query.QueryInputBoundary; + /** * The controller for the query use case. */ diff --git a/src/main/java/interface_adapter/query/QueryPresenter.java b/src/main/java/interface_adapter/query/QueryPresenter.java index 746b6a42d..aa5b152a4 100644 --- a/src/main/java/interface_adapter/query/QueryPresenter.java +++ b/src/main/java/interface_adapter/query/QueryPresenter.java @@ -2,11 +2,12 @@ import entity.RankHistory; import interface_adapter.ViewManagerModel; +import use_case.query.QueryOutputBoundary; /** * The presenter for query viewing. */ -public class QueryPresenter { +public class QueryPresenter implements QueryOutputBoundary { private final QueryViewModel queryViewModel; private final ViewManagerModel viewManagerModel; diff --git a/src/main/java/view/LoggedInView.java b/src/main/java/view/LoggedInView.java index 651ebdb44..33f364335 100644 --- a/src/main/java/view/LoggedInView.java +++ b/src/main/java/view/LoggedInView.java @@ -98,7 +98,7 @@ public void actionPerformed(ActionEvent evt) { if (evt.getSource().equals(showRankHistory)) { final LoggedInState currentState = loggedInViewModel.getState(); - QueryController.execute( + queryController.execute( currentState.getUsername() ); } From 63573941aec4aca2000a1cad9217ce8df76d1a00 Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Mon, 2 Dec 2024 11:50:50 -0500 Subject: [PATCH 070/125] Back button added in Profile view without real actionlistener --- src/main/java/view/ProfileView.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/view/ProfileView.java b/src/main/java/view/ProfileView.java index 8f7c740c4..e716ca3fa 100644 --- a/src/main/java/view/ProfileView.java +++ b/src/main/java/view/ProfileView.java @@ -25,6 +25,8 @@ public class ProfileView extends JPanel implements ActionListener, PropertyChang private final JLabel username; private final JLabel currentRankPoint; + private final JButton back; + public ProfileView(ViewManagerModel viewManagerModel, ShowProfileViewModel showProfileViewModel) { this.showProfileViewModel = showProfileViewModel; this.showProfileViewModel.addPropertyChangeListener(this); @@ -40,11 +42,22 @@ public ProfileView(ViewManagerModel viewManagerModel, ShowProfileViewModel showP final JLabel rankPointInfo = new JLabel("Current rank point: "); currentRankPoint = new JLabel(); + back = new JButton("Back"); + + back.addActionListener( + evt -> { + if (evt.getSource().equals(back)) { + System.out.println("back button clicked"); + } + } + ); + this.add(title); this.add(usernameInfo); this.add(username); this.add(rankPointInfo); this.add(currentRankPoint); + this.add(back); } /** From cd6e646c67f9cf77bc6df69955b7e23b28738e39 Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Mon, 2 Dec 2024 13:05:17 -0500 Subject: [PATCH 071/125] All 'Note' related package reserved from course repo deleted, deleted redundent 'main' class, rename 'main_ck' to 'MainChessAPP', rename 'CK_ChessAppBuilder to 'ChessAppBuilder'' --- src/main/java/app/CK_ChessAppBuilder.java | 67 ----------- src/main/java/app/ChessAppBuilder.java | 19 +--- .../app/{Main_ck.java => MainChessAPP.java} | 4 +- src/main/java/app/MainChessApp.java | 25 ---- src/main/java/app/MainNoteApplication.java | 56 --------- src/main/java/app/NoteAppBuilder.java | 83 -------------- .../data_access/DBNoteDataAccessObject.java | 107 ------------------ .../note/NoteController.java | 28 ----- .../interface_adapter/note/NotePresenter.java | 38 ------- .../interface_adapter/note/NoteState.java | 26 ----- .../interface_adapter/note/NoteViewModel.java | 13 --- .../use_case/note/DataAccessException.java | 10 -- .../note/NoteDataAccessInterface.java | 30 ----- .../java/use_case/note/NoteInputBoundary.java | 19 ---- .../java/use_case/note/NoteInteractor.java | 59 ---------- .../use_case/note/NoteOutputBoundary.java | 18 --- src/main/java/view/NoteView.java | 95 ---------------- 17 files changed, 5 insertions(+), 692 deletions(-) delete mode 100644 src/main/java/app/CK_ChessAppBuilder.java rename src/main/java/app/{Main_ck.java => MainChessAPP.java} (96%) delete mode 100644 src/main/java/app/MainChessApp.java delete mode 100644 src/main/java/app/MainNoteApplication.java delete mode 100644 src/main/java/app/NoteAppBuilder.java delete mode 100644 src/main/java/data_access/DBNoteDataAccessObject.java delete mode 100644 src/main/java/interface_adapter/note/NoteController.java delete mode 100644 src/main/java/interface_adapter/note/NotePresenter.java delete mode 100644 src/main/java/interface_adapter/note/NoteState.java delete mode 100644 src/main/java/interface_adapter/note/NoteViewModel.java delete mode 100644 src/main/java/use_case/note/DataAccessException.java delete mode 100644 src/main/java/use_case/note/NoteDataAccessInterface.java delete mode 100644 src/main/java/use_case/note/NoteInputBoundary.java delete mode 100644 src/main/java/use_case/note/NoteInteractor.java delete mode 100644 src/main/java/use_case/note/NoteOutputBoundary.java delete mode 100644 src/main/java/view/NoteView.java diff --git a/src/main/java/app/CK_ChessAppBuilder.java b/src/main/java/app/CK_ChessAppBuilder.java deleted file mode 100644 index e7012380a..000000000 --- a/src/main/java/app/CK_ChessAppBuilder.java +++ /dev/null @@ -1,67 +0,0 @@ -package app; - -import data_access.ChessDataAccessObject; -import entity.Board; -import entity.Game; -import interface_adapter.ViewManagerModel; -import interface_adapter.move.MoveController; -import interface_adapter.move.MovePresenter; -import interface_adapter.move.MoveViewModel; -import use_case.move.MoveInteractor; -import use_case.move.MoveOutputBoundary; -import view.ChessBoardView; - -/** - * Builder for the Note Application. - */ -public class CK_ChessAppBuilder { - public static final int HEIGHT = 800; - public static final int WIDTH = 800; - // TODO change to ChessDataAccessInterface once implemented - private ChessDataAccessObject chessDataAccessObject; - private MoveViewModel moveViewModel = new MoveViewModel(); - private final ViewManagerModel viewManagerModel = new ViewManagerModel(); - private ChessBoardView chessBoardView; - private MoveInteractor moveInteractor; - - /** - * Set the ChessDAO to be used in this application. - * @param chessDataAccess the DAO to use - * @return this builder - */ - public CK_ChessAppBuilder addChessDAO(ChessDataAccessObject chessDataAccess) { - chessDataAccessObject = chessDataAccess; - return this; - } - - /** - * Creates the objects for the Move Use Case and connects the ChessBoardView to Move controller. - * @return this builder - */ - public CK_ChessAppBuilder addMoveUseCase() { - final MoveOutputBoundary moveOutPutBoundary = new MovePresenter(moveViewModel, viewManagerModel); - Board board = new Board(); - Game game = new Game(board, true); - moveInteractor = new MoveInteractor( - chessDataAccessObject, moveOutPutBoundary, game); - - final MoveController moveController = new MoveController(moveInteractor); - chessBoardView.setMoveController(moveController); - return this; - } - - /** - * Creates the ChessBoardView and underlying MoveViewModel. - * @return this builder - */ - public CK_ChessAppBuilder addMoveView() { - moveViewModel = new MoveViewModel(); - final MoveController moveController = new MoveController(moveInteractor); - chessBoardView = new ChessBoardView(moveViewModel, moveController); - return this; - } - - public ChessBoardView buildChessBoardView() { - return chessBoardView; - } -} diff --git a/src/main/java/app/ChessAppBuilder.java b/src/main/java/app/ChessAppBuilder.java index 752666d46..5bc5118c2 100644 --- a/src/main/java/app/ChessAppBuilder.java +++ b/src/main/java/app/ChessAppBuilder.java @@ -1,8 +1,5 @@ package app; -import javax.swing.JFrame; -import javax.swing.WindowConstants; - import data_access.ChessDataAccessObject; import entity.Board; import entity.Game; @@ -15,7 +12,7 @@ import view.ChessBoardView; /** - * Builder for the Note Application. + * Builder for the Chess Application. */ public class ChessAppBuilder { public static final int HEIGHT = 800; @@ -64,17 +61,7 @@ public ChessAppBuilder addMoveView() { return this; } - /** - * Builds the app. - * @return the JFrame for the app - */ - public JFrame build() { - final JFrame frame = new JFrame(); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - frame.setTitle("Chess App"); - frame.setSize(WIDTH, HEIGHT); - - frame.add(chessBoardView); - return frame; + public ChessBoardView buildChessBoardView() { + return chessBoardView; } } diff --git a/src/main/java/app/Main_ck.java b/src/main/java/app/MainChessAPP.java similarity index 96% rename from src/main/java/app/Main_ck.java rename to src/main/java/app/MainChessAPP.java index 463a744e7..35d3e5f60 100644 --- a/src/main/java/app/Main_ck.java +++ b/src/main/java/app/MainChessAPP.java @@ -18,7 +18,7 @@ /** * Main that activates login page. */ -public class Main_ck { +public class MainChessAPP { /** * The main method for starting the program with an external database used to persist user data. @@ -57,7 +57,7 @@ public static void main(String[] args) { views.add(loggedInView, loggedInView.getViewName()); views.add(profileView, profileView.getViewName()); - final CK_ChessAppBuilder chessAppBuilder = new CK_ChessAppBuilder(); + final ChessAppBuilder chessAppBuilder = new ChessAppBuilder(); chessAppBuilder.addChessDAO(new ChessDataAccessObject()) .addMoveView() .addMoveUseCase(); diff --git a/src/main/java/app/MainChessApp.java b/src/main/java/app/MainChessApp.java deleted file mode 100644 index 54aa50c4e..000000000 --- a/src/main/java/app/MainChessApp.java +++ /dev/null @@ -1,25 +0,0 @@ -package app; - -import data_access.ChessDataAccessObject; - -/** - * This is the main chess app. - */ -public class MainChessApp { - - /** - * Main method. - * @param args commandline arguments - */ - public static void main(String[] args) { - - // TODO change to ChessDataAccessInterface once implemented - final ChessDataAccessObject chessDataAccessObject = new ChessDataAccessObject(); - - final ChessAppBuilder chessAppBuilder = new ChessAppBuilder(); - chessAppBuilder.addChessDAO(chessDataAccessObject) - .addMoveView() - .addMoveUseCase().build().setVisible(true); - - } -} diff --git a/src/main/java/app/MainNoteApplication.java b/src/main/java/app/MainNoteApplication.java deleted file mode 100644 index c37860156..000000000 --- a/src/main/java/app/MainNoteApplication.java +++ /dev/null @@ -1,56 +0,0 @@ -package app; - -import data_access.DBNoteDataAccessObject; -import use_case.note.NoteDataAccessInterface; - -/** - * An application where we can view and add to a note stored by a user. - *

- * This is a minimal example of using the password-protected user API from lab 5, - * but demonstrating the endpoint allowing you to store an arbitrary JSON object. - * This functionality could be used in any project where your team wants to persist - * data which is then accessible across devices.

- *

The code is intentionally somewhat incomplete to leave work to be done if your - * team were to choose to work on a project which would require similar functionality. - * For example, we have intentionally not created a full "Note" entity here, but - * rather just represented a note as a string. - *

- * The ViewManager code has also been removed, since this minimal program only requires a single - * view. Your team may wish to bring back the ViewManager or make your own implementation of supporting - * switching between views depending on your project. - */ -public class MainNoteApplication { - - /** - * The main entry point of the application. - *

- * The program will show you the note currently saved in the system. - * You are able to edit it and then save it to the system. You can refresh - * to update the note to reflect what was saved most recently. This - * uses the API from lab, so there is one database storing the note, - * which means that if anyone updates the note, that is what you will - * see when you refresh. - *

- * You can generalize the code to allow you to - * specify which "user" to save the note for, which will allow your team - * to store information specific to your team which is password-protected. - * The username and password used in this application are currently for - * user jonathan_calver2, but you can change that. As you did in lab 3, - * you will likely want to store password information locally rather than - * in your repo. Or you can require the user to enter their credentials - * in your application; it just depends on what your program's main - * functionality. - *

- * @param args commandline arguments are ignored - */ - public static void main(String[] args) { - - // create the data access and inject it into our builder! - final NoteDataAccessInterface noteDataAccess = new DBNoteDataAccessObject(); - - final NoteAppBuilder builder = new NoteAppBuilder(); - builder.addNoteDAO(noteDataAccess) - .addNoteView() - .addNoteUseCase().build().setVisible(true); - } -} diff --git a/src/main/java/app/NoteAppBuilder.java b/src/main/java/app/NoteAppBuilder.java deleted file mode 100644 index a68cb9ad6..000000000 --- a/src/main/java/app/NoteAppBuilder.java +++ /dev/null @@ -1,83 +0,0 @@ -package app; - -import javax.swing.JFrame; -import javax.swing.WindowConstants; - -import interface_adapter.note.NoteController; -import interface_adapter.note.NotePresenter; -import interface_adapter.note.NoteViewModel; -import use_case.note.NoteDataAccessInterface; -import use_case.note.NoteInteractor; -import use_case.note.NoteOutputBoundary; -import view.NoteView; - -/** - * Builder for the Note Application. - */ -public class NoteAppBuilder { - public static final int HEIGHT = 300; - public static final int WIDTH = 400; - private NoteDataAccessInterface noteDAO; - private NoteViewModel noteViewModel = new NoteViewModel(); - private NoteView noteView; - private NoteInteractor noteInteractor; - - /** - * Sets the NoteDAO to be used in this application. - * @param noteDataAccess the DAO to use - * @return this builder - */ - public NoteAppBuilder addNoteDAO(NoteDataAccessInterface noteDataAccess) { - noteDAO = noteDataAccess; - return this; - } - - /** - * Creates the objects for the Note Use Case and connects the NoteView to its - * controller. - *

This method must be called after addNoteView!

- * @return this builder - * @throws RuntimeException if this method is called before addNoteView - */ - public NoteAppBuilder addNoteUseCase() { - final NoteOutputBoundary noteOutputBoundary = new NotePresenter(noteViewModel); - noteInteractor = new NoteInteractor( - noteDAO, noteOutputBoundary); - - final NoteController controller = new NoteController(noteInteractor); - if (noteView == null) { - throw new RuntimeException("addNoteView must be called before addNoteUseCase"); - } - noteView.setNoteController(controller); - return this; - } - - /** - * Creates the NoteView and underlying NoteViewModel. - * @return this builder - */ - public NoteAppBuilder addNoteView() { - noteViewModel = new NoteViewModel(); - noteView = new NoteView(noteViewModel); - return this; - } - - /** - * Builds the application. - * @return the JFrame for the application - */ - public JFrame build() { - final JFrame frame = new JFrame(); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - frame.setTitle("Note Application"); - frame.setSize(WIDTH, HEIGHT); - - frame.add(noteView); - - // refresh so that the note will be visible when we start the program - noteInteractor.executeRefresh(); - - return frame; - - } -} diff --git a/src/main/java/data_access/DBNoteDataAccessObject.java b/src/main/java/data_access/DBNoteDataAccessObject.java deleted file mode 100644 index dadb0cab0..000000000 --- a/src/main/java/data_access/DBNoteDataAccessObject.java +++ /dev/null @@ -1,107 +0,0 @@ -package data_access; - -import java.io.IOException; - -import org.json.JSONException; -import org.json.JSONObject; - -import entity.User; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; -import use_case.note.DataAccessException; -import use_case.note.NoteDataAccessInterface; - -/** - * The DAO for accessing notes stored in the database. - *

This class demonstrates how your group can use the password-protected user - * endpoints of the API used in lab 5 to store persistent data in your program. - *

- *

You can also refer to the lab 5 code for signing up a new user and other use cases. - *

- * See - * - * the documentation - * of the API for more details. - */ -public class DBNoteDataAccessObject implements NoteDataAccessInterface { - private static final int SUCCESS_CODE = 200; - private static final int CREDENTIAL_ERROR = 401; - private static final String CONTENT_TYPE_LABEL = "Content-Type"; - private static final String CONTENT_TYPE_JSON = "application/json"; - private static final String STATUS_CODE_LABEL = "status_code"; - private static final String USERNAME = "username"; - private static final String PASSWORD = "password"; - private static final String MESSAGE = "message"; - - @Override - public String saveNote(User user, String note) throws DataAccessException { - final OkHttpClient client = new OkHttpClient().newBuilder() - .build(); - - // POST METHOD - final MediaType mediaType = MediaType.parse(CONTENT_TYPE_JSON); - final JSONObject requestBody = new JSONObject(); - requestBody.put(USERNAME, user.getName()); - requestBody.put(PASSWORD, user.getPassword()); - final JSONObject extra = new JSONObject(); - extra.put("note", note); - requestBody.put("info", extra); - final RequestBody body = RequestBody.create(requestBody.toString(), mediaType); - final Request request = new Request.Builder() - .url("http://vm003.teach.cs.toronto.edu:20112/modifyUserInfo") - .method("PUT", body) - .addHeader(CONTENT_TYPE_LABEL, CONTENT_TYPE_JSON) - .build(); - try { - final Response response = client.newCall(request).execute(); - - final JSONObject responseBody = new JSONObject(response.body().string()); - - if (responseBody.getInt(STATUS_CODE_LABEL) == SUCCESS_CODE) { - return loadNote(user); - } - else if (responseBody.getInt(STATUS_CODE_LABEL) == CREDENTIAL_ERROR) { - throw new DataAccessException("message could not be found or password was incorrect"); - } - else { - throw new DataAccessException("database error: " + responseBody.getString(MESSAGE)); - } - } - catch (IOException | JSONException ex) { - throw new DataAccessException(ex.getMessage()); - } - } - - @Override - public String loadNote(User user) throws DataAccessException { - // Make an API call to get the user object. - final String username = user.getName(); - final OkHttpClient client = new OkHttpClient().newBuilder().build(); - final Request request = new Request.Builder() - .url(String.format("http://vm003.teach.cs.toronto.edu:20112/user?username=%s", username)) - .addHeader("Content-Type", CONTENT_TYPE_JSON) - .build(); - try { - final Response response = client.newCall(request).execute(); - - final JSONObject responseBody = new JSONObject(response.body().string()); - - if (responseBody.getInt(STATUS_CODE_LABEL) == SUCCESS_CODE) { - final JSONObject userJSONObject = responseBody.getJSONObject("user"); - final JSONObject data = userJSONObject.getJSONObject("info"); - return data.getString("note"); - } - else { - throw new DataAccessException(responseBody.getString(MESSAGE)); - } - } - catch (IOException | JSONException ex) { - throw new RuntimeException(ex); - } - } -} diff --git a/src/main/java/interface_adapter/note/NoteController.java b/src/main/java/interface_adapter/note/NoteController.java deleted file mode 100644 index e3e5dfb32..000000000 --- a/src/main/java/interface_adapter/note/NoteController.java +++ /dev/null @@ -1,28 +0,0 @@ -package interface_adapter.note; - -import use_case.note.NoteInputBoundary; - -/** - * Controller for our Note related Use Cases. - */ -public class NoteController { - - private final NoteInputBoundary noteInteractor; - - public NoteController(NoteInputBoundary noteInteractor) { - this.noteInteractor = noteInteractor; - } - - /** - * Executes the Note related Use Cases. - * @param note the note to be recorded - */ - public void execute(String note) { - if (note != null) { - noteInteractor.executeSave(note); - } - else { - noteInteractor.executeRefresh(); - } - } -} diff --git a/src/main/java/interface_adapter/note/NotePresenter.java b/src/main/java/interface_adapter/note/NotePresenter.java deleted file mode 100644 index d4e416165..000000000 --- a/src/main/java/interface_adapter/note/NotePresenter.java +++ /dev/null @@ -1,38 +0,0 @@ -package interface_adapter.note; - -import use_case.note.NoteOutputBoundary; - -/** - * The presenter for our Note viewing and editing program. - */ -public class NotePresenter implements NoteOutputBoundary { - - private final NoteViewModel noteViewModel; - - public NotePresenter(NoteViewModel noteViewModel) { - this.noteViewModel = noteViewModel; - } - - /** - * Prepares the success view for the Note related Use Cases. - * - * @param note the output data - */ - @Override - public void prepareSuccessView(String note) { - noteViewModel.getState().setNote(note); - noteViewModel.getState().setError(null); - noteViewModel.firePropertyChanged(); - } - - /** - * Prepares the failure view for the Note related Use Cases. - * - * @param errorMessage the explanation of the failure - */ - @Override - public void prepareFailView(String errorMessage) { - noteViewModel.getState().setError(errorMessage); - noteViewModel.firePropertyChanged(); - } -} diff --git a/src/main/java/interface_adapter/note/NoteState.java b/src/main/java/interface_adapter/note/NoteState.java deleted file mode 100644 index c5b2234d6..000000000 --- a/src/main/java/interface_adapter/note/NoteState.java +++ /dev/null @@ -1,26 +0,0 @@ -package interface_adapter.note; - -/** - * The State for a note. - *

For this example, a note is simplay a string.

- */ -public class NoteState { - private String note = ""; - private String error; - - public String getNote() { - return note; - } - - public void setNote(String note) { - this.note = note; - } - - public void setError(String errorMessage) { - this.error = errorMessage; - } - - public String getError() { - return error; - } -} diff --git a/src/main/java/interface_adapter/note/NoteViewModel.java b/src/main/java/interface_adapter/note/NoteViewModel.java deleted file mode 100644 index 6e185d0fa..000000000 --- a/src/main/java/interface_adapter/note/NoteViewModel.java +++ /dev/null @@ -1,13 +0,0 @@ -package interface_adapter.note; - -import interface_adapter.ViewModel; - -/** - * The ViewModel for the NoteView. - */ -public class NoteViewModel extends ViewModel { - public NoteViewModel() { - super("note"); - setState(new NoteState()); - } -} diff --git a/src/main/java/use_case/note/DataAccessException.java b/src/main/java/use_case/note/DataAccessException.java deleted file mode 100644 index b8c17920d..000000000 --- a/src/main/java/use_case/note/DataAccessException.java +++ /dev/null @@ -1,10 +0,0 @@ -package use_case.note; - -/** - * Exception thrown when there is an error with accessing data. - */ -public class DataAccessException extends Exception { - public DataAccessException(String string) { - super(string); - } -} diff --git a/src/main/java/use_case/note/NoteDataAccessInterface.java b/src/main/java/use_case/note/NoteDataAccessInterface.java deleted file mode 100644 index b71597828..000000000 --- a/src/main/java/use_case/note/NoteDataAccessInterface.java +++ /dev/null @@ -1,30 +0,0 @@ -package use_case.note; - -import entity.User; - -/** - * Interface for the NoteDAO. It consists of methods for - * both loading and saving a note. - */ -public interface NoteDataAccessInterface { - - /** - * Saves a note for a given user. This will replace any existing note. - *

The password of the user must match that of the user saved in the system.

- * @param user the user information associated with the note - * @param note the note to be saved - * @return the contents of the note - * @throws DataAccessException if the user's note can not be saved for any reason - */ - String saveNote(User user, String note) throws DataAccessException; - - /** - * Returns the note associated with the user. The password - * is not checked, so anyone can read the information. - * @param user the user information associated with the note - * @return the contents of the note - * @throws DataAccessException if the user's note can not be loaded for any reason - */ - String loadNote(User user) throws DataAccessException; - -} diff --git a/src/main/java/use_case/note/NoteInputBoundary.java b/src/main/java/use_case/note/NoteInputBoundary.java deleted file mode 100644 index b41da9bf5..000000000 --- a/src/main/java/use_case/note/NoteInputBoundary.java +++ /dev/null @@ -1,19 +0,0 @@ -package use_case.note; - -/** - * The Input Boundary for our note-related use cases. Since they are closely related, - * we have included them both in the same interface for simplicity. - */ -public interface NoteInputBoundary { - - /** - * Executes the refresh note use case. - */ - void executeRefresh(); - - /** - * Executes the save note use case. - * @param message the input data - */ - void executeSave(String message); -} diff --git a/src/main/java/use_case/note/NoteInteractor.java b/src/main/java/use_case/note/NoteInteractor.java deleted file mode 100644 index 369e9309a..000000000 --- a/src/main/java/use_case/note/NoteInteractor.java +++ /dev/null @@ -1,59 +0,0 @@ -package use_case.note; - -import entity.User; - -/** - * The "Use Case Interactor" for our two note-related use cases of refreshing - * the contents of the note and saving the contents of the note. Since they - * are closely related, we have combined them here for simplicity. - */ -public class NoteInteractor implements NoteInputBoundary { - - private final NoteDataAccessInterface noteDataAccessInterface; - private final NoteOutputBoundary noteOutputBoundary; - // Note: this program has it hardcoded which user object it is getting data for; - // you could change this if you wanted to generalize the code. For example, - // you might allow a user of the program to create a new note, which you - // could store as a "user" through the API OR you might maintain all notes - // in a JSON object stored in one common "user" stored through the API. - private final User user = new User("jonathan_calver2", "abc123"); - - public NoteInteractor(NoteDataAccessInterface noteDataAccessInterface, - NoteOutputBoundary noteOutputBoundary) { - this.noteDataAccessInterface = noteDataAccessInterface; - this.noteOutputBoundary = noteOutputBoundary; - } - - /** - * Executes the refresh note use case. - * - */ - @Override - public void executeRefresh() { - try { - - final String note = noteDataAccessInterface.loadNote(user); - noteOutputBoundary.prepareSuccessView(note); - } - catch (DataAccessException ex) { - noteOutputBoundary.prepareFailView(ex.getMessage()); - } - } - - /** - * Executes the save note use case. - * - * @param note the input data - */ - @Override - public void executeSave(String note) { - try { - - final String updatedNote = noteDataAccessInterface.saveNote(user, note); - noteOutputBoundary.prepareSuccessView(updatedNote); - } - catch (DataAccessException ex) { - noteOutputBoundary.prepareFailView(ex.getMessage()); - } - } -} diff --git a/src/main/java/use_case/note/NoteOutputBoundary.java b/src/main/java/use_case/note/NoteOutputBoundary.java deleted file mode 100644 index c0c2bb1d0..000000000 --- a/src/main/java/use_case/note/NoteOutputBoundary.java +++ /dev/null @@ -1,18 +0,0 @@ -package use_case.note; - -/** - * The output boundary for the Login Use Case. - */ -public interface NoteOutputBoundary { - /** - * Prepares the success view for the Note related Use Cases. - * @param message the output data - */ - void prepareSuccessView(String message); - - /** - * Prepares the failure view for the Note related Use Cases. - * @param errorMessage the explanation of the failure - */ - void prepareFailView(String errorMessage); -} diff --git a/src/main/java/view/NoteView.java b/src/main/java/view/NoteView.java deleted file mode 100644 index 331d76493..000000000 --- a/src/main/java/view/NoteView.java +++ /dev/null @@ -1,95 +0,0 @@ -package view; - -import java.awt.Component; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; - -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JTextArea; - -import interface_adapter.note.NoteController; -import interface_adapter.note.NoteState; -import interface_adapter.note.NoteViewModel; - -/** - * The View for when the user is viewing a note in the program. - */ -public class NoteView extends JPanel implements ActionListener, PropertyChangeListener { - - private final NoteViewModel noteViewModel; - - private final JLabel noteName = new JLabel("note for jonathan_calver2"); - private final JTextArea noteInputField = new JTextArea(); - - private final JButton saveButton = new JButton("Save"); - private final JButton refreshButton = new JButton("Refresh"); - private NoteController noteController; - - public NoteView(NoteViewModel noteViewModel) { - - noteName.setAlignmentX(Component.CENTER_ALIGNMENT); - this.noteViewModel = noteViewModel; - this.noteViewModel.addPropertyChangeListener(this); - - final JPanel buttons = new JPanel(); - buttons.add(saveButton); - buttons.add(refreshButton); - - saveButton.addActionListener( - evt -> { - if (evt.getSource().equals(saveButton)) { - noteController.execute(noteInputField.getText()); - - } - } - ); - - refreshButton.addActionListener( - evt -> { - if (evt.getSource().equals(refreshButton)) { - noteController.execute(null); - - } - } - ); - - this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - - this.add(noteName); - this.add(noteInputField); - this.add(buttons); - } - - /** - * React to a button click that results in evt. - * @param evt the ActionEvent to react to - */ - public void actionPerformed(ActionEvent evt) { - System.out.println("Click " + evt.getActionCommand()); - } - - @Override - public void propertyChange(PropertyChangeEvent evt) { - final NoteState state = (NoteState) evt.getNewValue(); - setFields(state); - if (state.getError() != null) { - JOptionPane.showMessageDialog(this, state.getError(), - "Error", JOptionPane.ERROR_MESSAGE); - } - } - - private void setFields(NoteState state) { - noteInputField.setText(state.getNote()); - } - - public void setNoteController(NoteController controller) { - this.noteController = controller; - } -} - From ba757d3e74a2546421a7466d70f589aee6ca97a6 Mon Sep 17 00:00:00 2001 From: 207moment Date: Mon, 2 Dec 2024 15:51:58 -0500 Subject: [PATCH 072/125] Daily puzzle view model starter code --- .../daily_puzzle/DailyPuzzleController.java | 22 ++++++++++++ .../daily_puzzle/DailyPuzzlePresenter.java | 36 +++++++++++++++++++ .../daily_puzzle/DailyPuzzleState.java | 34 ++++++++++++++++++ .../daily_puzzle/DailyPuzzleViewModel.java | 13 +++++++ .../DailyPuzzleInputboundary.java | 12 +++++++ 5 files changed, 117 insertions(+) create mode 100644 src/main/java/interface_adapter/daily_puzzle/DailyPuzzleController.java create mode 100644 src/main/java/interface_adapter/daily_puzzle/DailyPuzzlePresenter.java create mode 100644 src/main/java/interface_adapter/daily_puzzle/DailyPuzzleState.java create mode 100644 src/main/java/interface_adapter/daily_puzzle/DailyPuzzleViewModel.java create mode 100644 src/main/java/use_case/daily_puzzle/DailyPuzzleInputboundary.java diff --git a/src/main/java/interface_adapter/daily_puzzle/DailyPuzzleController.java b/src/main/java/interface_adapter/daily_puzzle/DailyPuzzleController.java new file mode 100644 index 000000000..4325bcf51 --- /dev/null +++ b/src/main/java/interface_adapter/daily_puzzle/DailyPuzzleController.java @@ -0,0 +1,22 @@ +package interface_adapter.daily_puzzle; + +import use_case.daily_puzzle.DailyPuzzleInputboundary; + +/** + * Controller for the daily puzzle use case. + */ +public class DailyPuzzleController { + + private DailyPuzzleInputboundary dailyPuzzleInteractor; + + public DailyPuzzleController(DailyPuzzleInputboundary interactor) { + this.dailyPuzzleInteractor = interactor; + } + + /** + * Executes the daily puzzle use case. + */ + public void execute() { + dailyPuzzleInteractor.executeDailyPuzzle(); + } +} diff --git a/src/main/java/interface_adapter/daily_puzzle/DailyPuzzlePresenter.java b/src/main/java/interface_adapter/daily_puzzle/DailyPuzzlePresenter.java new file mode 100644 index 000000000..8bc1ac684 --- /dev/null +++ b/src/main/java/interface_adapter/daily_puzzle/DailyPuzzlePresenter.java @@ -0,0 +1,36 @@ +package interface_adapter.daily_puzzle; + +import java.util.ArrayList; + +import use_case.daily_puzzle.DailyPuzzleOutputBoundary; + +/** + * The presenter for daily puzzles. + */ +public class DailyPuzzlePresenter implements DailyPuzzleOutputBoundary { + + private final DailyPuzzleViewModel dailyPuzzleViewModel; + + public DailyPuzzlePresenter(DailyPuzzleViewModel dailyPuzzleViewModel) { + this.dailyPuzzleViewModel = dailyPuzzleViewModel; + } + + /** + * Prepares the success view for the daily puzzle use case. + * @param puzzleData contains puzzle setup and solution. + */ + @Override + public void prepareSuccessView(ArrayList puzzleData) { + + } + + /** + * Prepares failure view for daily puzzle. + * @param errorMessage Explanation of the failure + */ + @Override + public void prepareFailView(String errorMessage) { + dailyPuzzleViewModel.getState().setError(errorMessage); + dailyPuzzleViewModel.firePropertyChanged(); + } +} diff --git a/src/main/java/interface_adapter/daily_puzzle/DailyPuzzleState.java b/src/main/java/interface_adapter/daily_puzzle/DailyPuzzleState.java new file mode 100644 index 000000000..85b8e9b39 --- /dev/null +++ b/src/main/java/interface_adapter/daily_puzzle/DailyPuzzleState.java @@ -0,0 +1,34 @@ +package interface_adapter.daily_puzzle; + +import entity.Board; + +/** + * The state for a daily puzzle. + */ +public class DailyPuzzleState { + private static final String ROOK = "♖"; + private static final String BISHOP = "♗"; + private static final String QUEEN = "♕"; + private static final String KING = "♔"; + private static final String KNIGHT = "♘"; + private static final String PAWN = "♙"; + private Board board; + private String error; + + public Board getBoard() { + return board; + } + + public void setBoard(Board board) { + this.board = board; + } + + public String getError() { + return error; + } + + public void setError(String error) { + this.error = error; + } + +} diff --git a/src/main/java/interface_adapter/daily_puzzle/DailyPuzzleViewModel.java b/src/main/java/interface_adapter/daily_puzzle/DailyPuzzleViewModel.java new file mode 100644 index 000000000..ad42ee0fe --- /dev/null +++ b/src/main/java/interface_adapter/daily_puzzle/DailyPuzzleViewModel.java @@ -0,0 +1,13 @@ +package interface_adapter.daily_puzzle; + +import interface_adapter.ViewModel; + +/** + * ViewModel for daily puzzle. + */ +public class DailyPuzzleViewModel extends ViewModel { + public DailyPuzzleViewModel() { + super("daily puzzle"); + setState(new DailyPuzzleState()); + } +} diff --git a/src/main/java/use_case/daily_puzzle/DailyPuzzleInputboundary.java b/src/main/java/use_case/daily_puzzle/DailyPuzzleInputboundary.java new file mode 100644 index 000000000..9b44e9a0a --- /dev/null +++ b/src/main/java/use_case/daily_puzzle/DailyPuzzleInputboundary.java @@ -0,0 +1,12 @@ +package use_case.daily_puzzle; + +/** + * Input boundary for the daily puzzle use case. + */ +public interface DailyPuzzleInputboundary { + + /** + * Executes daily puzzle use case. + */ + void executeDailyPuzzle(); +} From 904fa95935032d69b0741c28d7ea5f511444eb6b Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Mon, 2 Dec 2024 16:32:46 -0500 Subject: [PATCH 073/125] delete 'note' test, modified 'ChessBoardViewTest' by create new 'testboard' and 'testgame' --- .../java/app/MainNoteApplicationTest.java | 112 ------------------ .../use_case/note/NoteInteractorTest.java | 46 ------- src/test/java/view/ChessBoardViewTest.java | 6 +- 3 files changed, 5 insertions(+), 159 deletions(-) delete mode 100644 src/test/java/app/MainNoteApplicationTest.java delete mode 100644 src/test/java/use_case/note/NoteInteractorTest.java diff --git a/src/test/java/app/MainNoteApplicationTest.java b/src/test/java/app/MainNoteApplicationTest.java deleted file mode 100644 index 025d970e2..000000000 --- a/src/test/java/app/MainNoteApplicationTest.java +++ /dev/null @@ -1,112 +0,0 @@ -package app; - -import entity.User; -import org.junit.Before; -import org.junit.Test; -import use_case.note.NoteDataAccessInterface; - -import javax.swing.*; -import java.awt.*; - -import static java.lang.Thread.sleep; -import static org.junit.Assert.*; - -public class MainNoteApplicationTest { - - private JFrame app; - - @Before - public void setUp() { - - // create the data access and inject it into our builder! - final NoteDataAccessInterface noteDataAccess = new NoteDataAccessInterface() { - - private String note = "test"; - - @Override - public String saveNote(User user, String note) { - this.note = note; - return note; - } - - @Override - public String loadNote(User user) { - return note; - } - }; - - final NoteAppBuilder builder = new NoteAppBuilder(); - app = builder.addNoteDAO(noteDataAccess) - .addNoteView() - .addNoteUseCase().build(); - - app.setVisible(true); - - } - - /** - * This is an example of an end-to-end test with a mocked database. - *

The code creates the application and directly tests to see that the GUI - * is updated as expected when the buttons and UI elements are interacted with. - *

- * You can run the test to visually see what happens. - */ - @Test - public void testEndToEnd() { - - Component[] components = ((JPanel)app.getRootPane().getContentPane().getComponents()[0]).getComponents(); - JTextArea textArea = null; - for (Component component : components) { - if (component instanceof JTextArea) { - textArea = (JTextArea) component; - assertEquals("test", textArea.getText()); - - } - } - - textArea.setText("test test"); - - - JButton save = null; - JButton load = null; - for (Component component : components) { - if (component instanceof JPanel) { - for (Component c : ((JPanel) component).getComponents()) { - if (c instanceof JButton) { - if (save != null) { - load = (JButton) c; - } - else { - save = (JButton) c; - } - } - } - } - } - - save.doClick(); - assertEquals("test test", textArea.getText()); - textArea.setText(""); - - System.out.println("cleared text; about to refresh..."); - // pause execution for a bit so we can visually see the changes on the screen - try { - sleep(1500); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - - load.doClick(); - assertEquals("test test", textArea.getText()); - - System.out.println("after refresh!"); - - // pause execution for a bit so we can visually see the changes on the screen - try { - sleep(1500); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - - } -} \ No newline at end of file diff --git a/src/test/java/use_case/note/NoteInteractorTest.java b/src/test/java/use_case/note/NoteInteractorTest.java deleted file mode 100644 index a3ed466b6..000000000 --- a/src/test/java/use_case/note/NoteInteractorTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package use_case.note; - -import entity.User; -import org.junit.Test; - -import static org.junit.Assert.*; - -public class NoteInteractorTest { - - @Test - public void testExecuteRefreshSuccess() { - - NoteDataAccessInterface noteDAO = new NoteDataAccessInterface() { - - - @Override - public String saveNote(User user, String note) { - return ""; - } - - - @Override - public String loadNote(User user) { - return "test"; - } - }; - - NoteOutputBoundary noteOB = new NoteOutputBoundary() { - @Override - public void prepareSuccessView(String message) { - assertEquals("test", message); - } - - @Override - public void prepareFailView(String errorMessage) { - fail(errorMessage); - } - }; - - NoteInteractor noteInteractor = new NoteInteractor(noteDAO, noteOB); - - noteInteractor.executeRefresh(); - - - } -} \ No newline at end of file diff --git a/src/test/java/view/ChessBoardViewTest.java b/src/test/java/view/ChessBoardViewTest.java index b100b4a9c..5186f0bdf 100644 --- a/src/test/java/view/ChessBoardViewTest.java +++ b/src/test/java/view/ChessBoardViewTest.java @@ -1,6 +1,8 @@ package view; import data_access.ChessDataAccessObject; +import entity.Board; +import entity.Game; import interface_adapter.ViewManagerModel; import interface_adapter.move.MoveController; import interface_adapter.move.MovePresenter; @@ -24,7 +26,9 @@ public static void main(String[] args) { MoveViewModel moveViewModel = new MoveViewModel(); ViewManagerModel viewManagerModel = new ViewManagerModel(); MoveOutputBoundary movePresenter = new MovePresenter(moveViewModel, viewManagerModel); - MoveInteractor TestInteractor = new MoveInteractor(moveDataAccessObject, movePresenter); + Board board = new Board(); + Game game = new Game(board, true); + MoveInteractor TestInteractor = new MoveInteractor(moveDataAccessObject, movePresenter, game); MoveController TestController = new MoveController(TestInteractor); ChessBoardView TestView = new ChessBoardView(TestModel, TestController); From 61d7eec6db1f1682fa44abe0820fef293d7e58c4 Mon Sep 17 00:00:00 2001 From: J0hnDing Date: Mon, 2 Dec 2024 17:08:59 -0500 Subject: [PATCH 074/125] Move now work, get valid moves in the interacter has not been implemented, turn switching has not been implemented --- src/main/java/entity/Board.java | 46 ++++++++++--- src/main/java/entity/ChessPiece.java | 3 + src/main/java/entity/King.java | 26 ++++++++ src/main/java/entity/Knight.java | 36 +++++++++++ src/main/java/entity/Pawn.java | 11 +++- .../java/interface_adapter/ViewModel.java | 6 +- .../interface_adapter/move/MovePresenter.java | 64 ++++++++++++++++++- .../interface_adapter/move/MoveViewModel.java | 14 +++- .../java/use_case/move/MoveInputdata.java | 2 +- .../java/use_case/move/MoveInteractor.java | 27 +++++++- .../use_case/move/MoveOutputBoundary.java | 1 - src/main/java/view/ChessBoardView.java | 54 ++++++++++++++-- 12 files changed, 264 insertions(+), 26 deletions(-) create mode 100644 src/main/java/entity/King.java create mode 100644 src/main/java/entity/Knight.java diff --git a/src/main/java/entity/Board.java b/src/main/java/entity/Board.java index d41279bb5..50ed58320 100644 --- a/src/main/java/entity/Board.java +++ b/src/main/java/entity/Board.java @@ -9,7 +9,39 @@ public class Board { private ChessPiece[][] grid; public Board() { - grid = new ChessPiece[8][8]; + ChessPiece[][] grid = new ChessPiece[8][8]; + + grid[0][0] = new Rook("White", 0, 0); + grid[0][1] = new Knight("White", 0, 1); + grid[0][2] = new Bishop("White", 0, 2); + grid[0][3] = new Queen("White", 0, 3); + grid[0][4] = new King("White", 0, 4); + grid[0][5] = new Bishop("White", 0, 5); + grid[0][6] = new Knight("White", 0, 6); + grid[0][7] = new Rook("White", 0, 7); + for (int i = 0; i < 8; i++) { + grid[1][i] = new Pawn("White", 1, i); + } + + grid[7][0] = new Rook("Black", 7, 0); + grid[7][1] = new Knight("Black", 7, 1); + grid[7][2] = new Bishop("Black", 7, 2); + grid[7][3] = new Queen("Black", 7, 3); + grid[7][4] = new King("Black", 7, 4); + grid[7][5] = new Bishop("Black", 7, 5); + grid[7][6] = new Knight("Black", 7, 6); + grid[7][7] = new Rook("Black", 7, 7); + for (int i = 0; i < 8; i++) { + grid[6][i] = new Pawn("Black", 6, i); + } + +// Set all empty squares to null + for (int row = 2; row < 6; row++) { + for (int col = 0; col < 8; col++) { + grid[row][col] = null; + } + } + this.grid = grid; } public Board(JSONObject boardFile) { @@ -22,7 +54,7 @@ public Board(JSONObject boardFile) { * @return bool */ public boolean isEmpty(int[] position) { - return grid[position[1]][position[0]] == null; + return grid[position[0]][position[1]] == null; } /** @@ -31,16 +63,14 @@ public boolean isEmpty(int[] position) { * @return Chesspiece */ public ChessPiece getPiece(int[] position) { - return grid[position[1]][position[0]]; + return grid[position[0]][position[1]]; } - public void clear(int[] position) { - grid[position[1]][position[0]] = null; - } public void moveToLocation(int[] position, ChessPiece piece) { - clear(piece.getPosition()); - grid[position[1]][position[0]] = piece; + grid[piece.getPosition()[0]][piece.getPosition()[1]] = null; + piece.setPosition(position); + grid[position[0]][position[1]] = piece; } } diff --git a/src/main/java/entity/ChessPiece.java b/src/main/java/entity/ChessPiece.java index 9291695e3..07a0d0575 100644 --- a/src/main/java/entity/ChessPiece.java +++ b/src/main/java/entity/ChessPiece.java @@ -27,4 +27,7 @@ public String getColor() { public int[] getPosition() { return this.position; } + public void setPosition(int[] position) { + this.position = position; + } } diff --git a/src/main/java/entity/King.java b/src/main/java/entity/King.java new file mode 100644 index 000000000..ba4f80eb5 --- /dev/null +++ b/src/main/java/entity/King.java @@ -0,0 +1,26 @@ +package entity; + +import java.util.ArrayList; + +public class King extends ChessPiece { + public King(String color, int x, int y) { + super(color, x, y); + } + + /** + * Returns all possible moves for a bishop from the given position on an 8x8 chessboard. + * + * @return A list of int arrays, each representing a valid move [newX, newY]. + */ + public ArrayList getValidMoves() { + final ArrayList validMoves = new ArrayList<>(); + final int x = this.getPosition()[0]; + final int y = this.getPosition()[1]; + validMoves.add(new int[]{x + 1, y}); + validMoves.add(new int[]{x - 1, y}); + validMoves.add(new int[]{x, y - 1}); + validMoves.add(new int[]{x, y + 1}); + validMoves.removeIf(move -> move[0] < 0 || move[0] >= 8 || move[1] < 0 || move[1] >= 8); + return validMoves; + } +} diff --git a/src/main/java/entity/Knight.java b/src/main/java/entity/Knight.java new file mode 100644 index 000000000..347b5ef7b --- /dev/null +++ b/src/main/java/entity/Knight.java @@ -0,0 +1,36 @@ +package entity; + +import java.util.ArrayList; + +public class Knight extends ChessPiece { + public Knight(String color, int x, int y) { + super(color, x, y); + } + + /** + * Returns all possible moves for a bishop from the given position on an 8x8 chessboard. + * + * @return A list of int arrays, each representing a valid move [newX, newY]. + */ + public ArrayList getValidMoves() { + final ArrayList validMoves = new ArrayList<>(); + final int x = this.getPosition()[0]; + final int y = this.getPosition()[1]; + + final int[][] potentialMoves = { + {x + 2, y + 1}, {x + 2, y - 1}, + {x - 2, y + 1}, {x - 2, y - 1}, + {x + 1, y + 2}, {x + 1, y - 2}, + {x - 1, y + 2}, {x - 1, y - 2} + }; + + // Add valid moves within board boundaries (0 to 7) + for (int[] move : potentialMoves) { + if (move[0] >= 0 && move[0] < 8 && move[1] >= 0 && move[1] < 8) { + validMoves.add(move); + } + } + + return validMoves; + } +} diff --git a/src/main/java/entity/Pawn.java b/src/main/java/entity/Pawn.java index 5171bf20a..971d52910 100644 --- a/src/main/java/entity/Pawn.java +++ b/src/main/java/entity/Pawn.java @@ -16,7 +16,16 @@ public ArrayList getValidMoves() { final int x = this.getPosition()[0]; final int y = this.getPosition()[1]; - //still to be implemented... + if (this.getColor().equals("White") && x != 7) { + validMoves.add(new int[]{x + 1, y + 1}); + validMoves.add(new int[]{x + 1, y - 1}); + validMoves.add(new int[]{x + 1, y}); + } else if (this.getColor().equals("Black") && x != 0) { + validMoves.add(new int[]{x - 1, y - 1}); + validMoves.add(new int[]{x - 1, y }); + validMoves.add(new int[]{x - 1, y + 1}); + } + validMoves.removeIf(move -> move[0] < 0 || move[1] < 0 || move[0] > 7 || move[1] > 7); return validMoves; } diff --git a/src/main/java/interface_adapter/ViewModel.java b/src/main/java/interface_adapter/ViewModel.java index 130d797a1..4c06a9080 100644 --- a/src/main/java/interface_adapter/ViewModel.java +++ b/src/main/java/interface_adapter/ViewModel.java @@ -14,7 +14,7 @@ public class ViewModel { private final String viewName; - private final PropertyChangeSupport support = new PropertyChangeSupport(this); + protected final PropertyChangeSupport support = new PropertyChangeSupport(this); private T state; @@ -53,6 +53,10 @@ public void firePropertyChanged(String propertyName) { this.support.firePropertyChange(propertyName, null, this.state); } + public void firePropertyChange(String propertyName, Object oldValue, Object newValue) { + this.support.firePropertyChange(propertyName, oldValue, newValue); + } + /** * Adds a PropertyChangeListener to this ViewModel. * @param listener The PropertyChangeListener to be added diff --git a/src/main/java/interface_adapter/move/MovePresenter.java b/src/main/java/interface_adapter/move/MovePresenter.java index 9380b8227..90bce3733 100644 --- a/src/main/java/interface_adapter/move/MovePresenter.java +++ b/src/main/java/interface_adapter/move/MovePresenter.java @@ -1,11 +1,14 @@ package interface_adapter.move; //import chariot.model.MoveInfo; +import chariot.util.Board; import interface_adapter.ViewManagerModel; import use_case.move.MoveInputdata; import use_case.move.MoveOutputBoundary; import use_case.move.MoveOutputdata; +import java.util.ArrayList; + /** * The presenter for Move use case. */ @@ -18,11 +21,66 @@ public MovePresenter(MoveViewModel moveViewModel, ViewManagerModel viewManagerMo this.viewManagerModel = viewManagerModel; } + public void prepareMove(MoveOutputdata input) { - // present the moved chess board - } + String[][] pieces = new String[8][8]; + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 8; j++) { + if (input.getBoard().isEmpty(new int[] {i, j})) { + pieces[7-i][j] = null; + } else { + if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.Bishop) { + if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { + pieces[7-i][j] = "♗"; + } else { + pieces[7-i][j] = "♝"; + } + } + else if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.Rook) { + if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { + pieces[7-i][j] = "♖"; + } else { + pieces[7-i][j] = "♜"; + } + } + else if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.Knight) { + if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { + pieces[7-i][j] = "♘"; + } else { + pieces[7-i][j] = "♞"; + } + } + else if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.Pawn) { + if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { + pieces[7-i][j] = "♙"; + } else { + pieces[7-i][j] = "♟"; + } + } + else if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.Queen) { + if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { + pieces[7-i][j]= "♕"; + } else { + pieces[7-i][j]= "♕"; + } + } + else if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.King) { + if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { + pieces[7-i][j] = "♔"; + } else { + pieces[7-i][j] = "♚"; + } + } + } + + } + } + ArrayList validMoves = input.getValidMoves(); + for (int[] move : validMoves) { + pieces[7-move[0]][move[1]] = "Valid"; + } - public void prepareSelect(MoveOutputdata input) { + moveViewModel.setPieces(pieces); // present the select chess board } diff --git a/src/main/java/interface_adapter/move/MoveViewModel.java b/src/main/java/interface_adapter/move/MoveViewModel.java index 4cdb522fe..fe0794167 100644 --- a/src/main/java/interface_adapter/move/MoveViewModel.java +++ b/src/main/java/interface_adapter/move/MoveViewModel.java @@ -1,6 +1,7 @@ package interface_adapter.move; import interface_adapter.ViewModel; +import view.ChessBoardView; /** * The ViewModel for the MoveView. @@ -8,7 +9,7 @@ public class MoveViewModel extends ViewModel { public static final String TITLE_LABEL = "Move View"; - + private String[][] piece; private final String[][] pieces = { {"♜", "♞", "♝", "♛", "♚", "♝", "♞", "♜"}, // Black major pieces {"♟", "♟", "♟", "♟", "♟", "♟", "♟", "♟"}, // Black pawns @@ -22,10 +23,19 @@ public class MoveViewModel extends ViewModel { public MoveViewModel() { super("move"); + this.piece = pieces; setState(new MoveState()); } public String[][] getPieces() { - return pieces; + return piece; } + + public void setPieces(String[][] input) { + String[][] oldPieces = this.piece; // Save the current state + this.piece = input; // Update with new state + support.firePropertyChange("pieces", oldPieces, input); + + } + } diff --git a/src/main/java/use_case/move/MoveInputdata.java b/src/main/java/use_case/move/MoveInputdata.java index 7a4bd4dde..26401730f 100644 --- a/src/main/java/use_case/move/MoveInputdata.java +++ b/src/main/java/use_case/move/MoveInputdata.java @@ -8,7 +8,7 @@ public class MoveInputdata { private final int[] position; public MoveInputdata(int[] input) { - this.position = input; + this.position = new int[]{input[1], input[0]}; } public int[] getPosition() { diff --git a/src/main/java/use_case/move/MoveInteractor.java b/src/main/java/use_case/move/MoveInteractor.java index a79229b97..c682b835f 100644 --- a/src/main/java/use_case/move/MoveInteractor.java +++ b/src/main/java/use_case/move/MoveInteractor.java @@ -1,6 +1,7 @@ package use_case.move; import java.util.ArrayList; +import java.util.Arrays; import entity.ChessPiece; import entity.Game; @@ -39,6 +40,14 @@ public void execute(MoveInputdata position) { if (game.getGameMode()) { select(pos); } + else if (game.getBoard().getPiece(pos) != null) { + if (game.getBoard().getPiece(pos).getColor().equals(game.getChesspiece_to_move().getColor())) { + select(pos); + } + else { + move(pos); + } + } else { move(pos); } @@ -60,22 +69,36 @@ private void select(int[] position) { game.setChesspiece_to_move(piece); game.switchMode(); final MoveOutputdata selectdata = new MoveOutputdata(validmoves(piece), game.getBoard()); - moveOutPutBoundary.prepareSelect(selectdata); + moveOutPutBoundary.prepareMove(selectdata); } } private void move(int[] pos) { final ArrayList validmoves = validmoves(game.getChesspiece_to_move()); - if (validmoves.contains(pos)) { + if (containsArray(validmoves, pos)) { game.getBoard().moveToLocation(pos, game.getChesspiece_to_move()); //Move the chess piece to location final MoveOutputdata movedata = new MoveOutputdata(new ArrayList<>(), game.getBoard()); moveOutPutBoundary.prepareMove(movedata); + game.switchMode(); } else { // Do Nothing since nothing happend final MoveOutputdata nulldata = new MoveOutputdata(new ArrayList<>(), game.getBoard()); moveOutPutBoundary.prepareMove(nulldata); + game.switchMode(); } } + + public static boolean containsArray(ArrayList list, int[] target) { + if (list == null || target == null) { + return false; + } + for (int[] array : list) { + if (Arrays.equals(array, target)) { + return true; + } + } + return false; + } } diff --git a/src/main/java/use_case/move/MoveOutputBoundary.java b/src/main/java/use_case/move/MoveOutputBoundary.java index 0e70da960..42a04de64 100644 --- a/src/main/java/use_case/move/MoveOutputBoundary.java +++ b/src/main/java/use_case/move/MoveOutputBoundary.java @@ -1,6 +1,5 @@ package use_case.move; public interface MoveOutputBoundary { - void prepareSelect(MoveOutputdata outputdata); void prepareMove(MoveOutputdata outputdata); } diff --git a/src/main/java/view/ChessBoardView.java b/src/main/java/view/ChessBoardView.java index 8f70257a9..975bce79e 100644 --- a/src/main/java/view/ChessBoardView.java +++ b/src/main/java/view/ChessBoardView.java @@ -46,10 +46,9 @@ public ChessBoardView(MoveViewModel moveViewModel, MoveController moveController // Set background color to alternate between black and white if ((row + col) % 2 == 0) { - button.setBackground(Color.WHITE); - } - else { - button.setBackground(Color.BLACK); + button.setBackground(Color.GRAY); + } else { + button.setBackground(Color.orange); } // Add pieces to the board @@ -58,8 +57,7 @@ public ChessBoardView(MoveViewModel moveViewModel, MoveController moveController // Set highlighted background color associate with valid moves. if (pieces[row][col].equals("Valid")) { button.setBackground(Color.YELLOW); - } - else { + } else { button.setText(pieces[row][col]); button.setFont(new Font("Serif", Font.BOLD, fontSize)); } @@ -81,10 +79,52 @@ public void setMoveController(MoveController moveController) { @Override public void actionPerformed(ActionEvent e) { System.out.println(e.getActionCommand()); + String[] parts = e.getActionCommand().split(","); // Split the string at the comma + // Convert the parts to integers + int x = Integer.parseInt(parts[0]); + int y = Integer.parseInt(parts[1]); + moveController.onClick(x, y); } @Override public void propertyChange(PropertyChangeEvent evt) { + if ("pieces".equals(evt.getPropertyName())) { + // Retrieve the updated pieces array + String[][] updatedPieces = (String[][]) evt.getNewValue(); + + // Update the board + for (int row = 0; row < numRow; row++) { + for (int col = 0; col < numCol; col++) { + // Find the button at this position + JButton button = (JButton) this.getComponent(row * numCol + col); + + // Reset button background color + if ((row + col) % 2 == 0) { + button.setBackground(Color.GRAY); + } else { + button.setBackground(Color.orange); + } + + // Update the button text and background based on the new pieces + if (updatedPieces[row][col] != null) { + if ("Valid".equals(updatedPieces[row][col])) { + button.setBackground(Color.YELLOW); // Highlight valid move + button.setText(""); // No text for "Valid" markers + } else { + button.setText(updatedPieces[row][col]); // Set piece text + button.setFont(new Font("Serif", Font.BOLD, fontSize)); + } + } else { + button.setText(""); // Clear text if no piece + } + } + } + // Refresh the UI + this.revalidate(); + this.repaint(); + } } -} + + +} \ No newline at end of file From 7f7baea16209a9bb6ac47f0c0599a2e683a479c1 Mon Sep 17 00:00:00 2001 From: 207moment Date: Mon, 2 Dec 2024 17:18:23 -0500 Subject: [PATCH 075/125] Addition of blank knight and king classes. --- src/main/java/entity/King.java | 18 ++++++++++++++++++ src/main/java/entity/Knight.java | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/main/java/entity/King.java create mode 100644 src/main/java/entity/Knight.java diff --git a/src/main/java/entity/King.java b/src/main/java/entity/King.java new file mode 100644 index 000000000..c83f4117e --- /dev/null +++ b/src/main/java/entity/King.java @@ -0,0 +1,18 @@ +package entity; + +import java.util.ArrayList; + +/** + * King piece. + */ +public class King extends ChessPiece { + public King(String color, int x, int y) { + super(color, x, y); + } + + @Override + public ArrayList getValidMoves() { + // to be implemented + return null; + } +} diff --git a/src/main/java/entity/Knight.java b/src/main/java/entity/Knight.java new file mode 100644 index 000000000..d069296cf --- /dev/null +++ b/src/main/java/entity/Knight.java @@ -0,0 +1,18 @@ +package entity; + +import java.util.ArrayList; + +/** + * Knight piece. + */ +public class Knight extends ChessPiece { + public Knight(String color, int x, int y) { + super(color, x, y); + } + + @Override + public ArrayList getValidMoves() { + // to be implemented + return null; + } +} From e944ad634570467df1a245fb7dfae8c3ca8ff521 Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Sat, 30 Nov 2024 19:48:32 -0500 Subject: [PATCH 076/125] README.md update --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ba1d22437..d64638d00 100644 --- a/README.md +++ b/README.md @@ -58,16 +58,21 @@ To Login: Click ```Login``` to navigate to a login page, enter username and pass ### Show Profile +User can view there profile (Contain User name and rank point currently) after login by click ```Show Profile``` after login. +Note: New user's rank point is set to ```0``` -### Generate daily puzzle +### Generate daily puzzle +// TODO ### Step by step move +// TODO + ## Usage Guide This meant to me used in order of ```Signup & Login``` → ```Generate daily puzzle``` → ```Step by step move``` From b3963e24ff34242bb54809342b900cf7e61e011c Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Mon, 2 Dec 2024 18:11:41 -0500 Subject: [PATCH 077/125] accessibility report added --- accessibility-report.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 accessibility-report.md diff --git a/accessibility-report.md b/accessibility-report.md new file mode 100644 index 000000000..70a3e6883 --- /dev/null +++ b/accessibility-report.md @@ -0,0 +1,22 @@ +## Principle of Universal desgin + ++ Equitable Use + + Users are allowed to input any String as their username, not restricted to english. User with none english name can benefit from this. ++ Flexibility in Use + + Features could add: Allowed user to pick board theme (ie., Black/white, light theme, dark theme). ++ Simple and Intuitive Use + + Move use are match with intuition. Click a piece to select, slick a grid to move ++ Perceptible Information + + This program can't accommodate user with visual disability currently. A potential feature might add to accommodate visual disability is allowed user to select other output device (ie., touch board) ++ Tolerance of Error + + Tolerating wrong click on grid that doesn't contain piece. Error message like "Can't select empty grid" doesn't sent, because click on empty grid is common that sent error message everytime wrong click happened will be annoyed. ++ Low Physical Effort + + The only interaction use need while play the chess game is clicking mose. ++ Size and Space for Approach and Use + + Size of the window (chess board) is adjustable. + +## Program Market ++ If I were to market my chess puzzle program, I would target chess enthusiasts and learners of all ages, particularly those seeking to improve their strategic thinking and problem-solving skills. The program would appeal to students and educators looking for engaging tools to teach or practice chess fundamentals, as well as casual players who enjoy the intellectual challenge of solving puzzles in their leisure time. Additionally, the program could attract competitive chess players aiming to refine their tactics through a curated collection of puzzles ranging from beginner to advanced levels. + +## People who can't take advantage of this App ++ People with dysgnosia is less likely to take advantage of this App, simply because this App is meant to be intellectually challenging. However, puzzle difficulty classification feature can be added and might accommodate people with dysgnosia. \ No newline at end of file From 82eec2da6ed327e80a240680dae3cbf6e7a06d38 Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Mon, 2 Dec 2024 11:50:50 -0500 Subject: [PATCH 078/125] Back button added in Profile view without real actionlistener --- src/main/java/view/ProfileView.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/view/ProfileView.java b/src/main/java/view/ProfileView.java index 8f7c740c4..e716ca3fa 100644 --- a/src/main/java/view/ProfileView.java +++ b/src/main/java/view/ProfileView.java @@ -25,6 +25,8 @@ public class ProfileView extends JPanel implements ActionListener, PropertyChang private final JLabel username; private final JLabel currentRankPoint; + private final JButton back; + public ProfileView(ViewManagerModel viewManagerModel, ShowProfileViewModel showProfileViewModel) { this.showProfileViewModel = showProfileViewModel; this.showProfileViewModel.addPropertyChangeListener(this); @@ -40,11 +42,22 @@ public ProfileView(ViewManagerModel viewManagerModel, ShowProfileViewModel showP final JLabel rankPointInfo = new JLabel("Current rank point: "); currentRankPoint = new JLabel(); + back = new JButton("Back"); + + back.addActionListener( + evt -> { + if (evt.getSource().equals(back)) { + System.out.println("back button clicked"); + } + } + ); + this.add(title); this.add(usernameInfo); this.add(username); this.add(rankPointInfo); this.add(currentRankPoint); + this.add(back); } /** From 7262da8601feaa37b8bb34f92b7f66d12c094fa3 Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Mon, 2 Dec 2024 13:05:17 -0500 Subject: [PATCH 079/125] All 'Note' related package reserved from course repo deleted, deleted redundent 'main' class, rename 'main_ck' to 'MainChessAPP', rename 'CK_ChessAppBuilder to 'ChessAppBuilder'' --- src/main/java/app/CK_ChessAppBuilder.java | 67 ----------- src/main/java/app/ChessAppBuilder.java | 19 +--- .../app/{Main_ck.java => MainChessAPP.java} | 4 +- src/main/java/app/MainChessApp.java | 25 ---- src/main/java/app/MainNoteApplication.java | 56 --------- src/main/java/app/NoteAppBuilder.java | 83 -------------- .../data_access/DBNoteDataAccessObject.java | 107 ------------------ .../note/NoteController.java | 28 ----- .../interface_adapter/note/NotePresenter.java | 38 ------- .../interface_adapter/note/NoteState.java | 26 ----- .../interface_adapter/note/NoteViewModel.java | 13 --- .../use_case/note/DataAccessException.java | 10 -- .../note/NoteDataAccessInterface.java | 30 ----- .../java/use_case/note/NoteInputBoundary.java | 19 ---- .../java/use_case/note/NoteInteractor.java | 59 ---------- .../use_case/note/NoteOutputBoundary.java | 18 --- src/main/java/view/NoteView.java | 95 ---------------- 17 files changed, 5 insertions(+), 692 deletions(-) delete mode 100644 src/main/java/app/CK_ChessAppBuilder.java rename src/main/java/app/{Main_ck.java => MainChessAPP.java} (96%) delete mode 100644 src/main/java/app/MainChessApp.java delete mode 100644 src/main/java/app/MainNoteApplication.java delete mode 100644 src/main/java/app/NoteAppBuilder.java delete mode 100644 src/main/java/data_access/DBNoteDataAccessObject.java delete mode 100644 src/main/java/interface_adapter/note/NoteController.java delete mode 100644 src/main/java/interface_adapter/note/NotePresenter.java delete mode 100644 src/main/java/interface_adapter/note/NoteState.java delete mode 100644 src/main/java/interface_adapter/note/NoteViewModel.java delete mode 100644 src/main/java/use_case/note/DataAccessException.java delete mode 100644 src/main/java/use_case/note/NoteDataAccessInterface.java delete mode 100644 src/main/java/use_case/note/NoteInputBoundary.java delete mode 100644 src/main/java/use_case/note/NoteInteractor.java delete mode 100644 src/main/java/use_case/note/NoteOutputBoundary.java delete mode 100644 src/main/java/view/NoteView.java diff --git a/src/main/java/app/CK_ChessAppBuilder.java b/src/main/java/app/CK_ChessAppBuilder.java deleted file mode 100644 index e7012380a..000000000 --- a/src/main/java/app/CK_ChessAppBuilder.java +++ /dev/null @@ -1,67 +0,0 @@ -package app; - -import data_access.ChessDataAccessObject; -import entity.Board; -import entity.Game; -import interface_adapter.ViewManagerModel; -import interface_adapter.move.MoveController; -import interface_adapter.move.MovePresenter; -import interface_adapter.move.MoveViewModel; -import use_case.move.MoveInteractor; -import use_case.move.MoveOutputBoundary; -import view.ChessBoardView; - -/** - * Builder for the Note Application. - */ -public class CK_ChessAppBuilder { - public static final int HEIGHT = 800; - public static final int WIDTH = 800; - // TODO change to ChessDataAccessInterface once implemented - private ChessDataAccessObject chessDataAccessObject; - private MoveViewModel moveViewModel = new MoveViewModel(); - private final ViewManagerModel viewManagerModel = new ViewManagerModel(); - private ChessBoardView chessBoardView; - private MoveInteractor moveInteractor; - - /** - * Set the ChessDAO to be used in this application. - * @param chessDataAccess the DAO to use - * @return this builder - */ - public CK_ChessAppBuilder addChessDAO(ChessDataAccessObject chessDataAccess) { - chessDataAccessObject = chessDataAccess; - return this; - } - - /** - * Creates the objects for the Move Use Case and connects the ChessBoardView to Move controller. - * @return this builder - */ - public CK_ChessAppBuilder addMoveUseCase() { - final MoveOutputBoundary moveOutPutBoundary = new MovePresenter(moveViewModel, viewManagerModel); - Board board = new Board(); - Game game = new Game(board, true); - moveInteractor = new MoveInteractor( - chessDataAccessObject, moveOutPutBoundary, game); - - final MoveController moveController = new MoveController(moveInteractor); - chessBoardView.setMoveController(moveController); - return this; - } - - /** - * Creates the ChessBoardView and underlying MoveViewModel. - * @return this builder - */ - public CK_ChessAppBuilder addMoveView() { - moveViewModel = new MoveViewModel(); - final MoveController moveController = new MoveController(moveInteractor); - chessBoardView = new ChessBoardView(moveViewModel, moveController); - return this; - } - - public ChessBoardView buildChessBoardView() { - return chessBoardView; - } -} diff --git a/src/main/java/app/ChessAppBuilder.java b/src/main/java/app/ChessAppBuilder.java index 752666d46..5bc5118c2 100644 --- a/src/main/java/app/ChessAppBuilder.java +++ b/src/main/java/app/ChessAppBuilder.java @@ -1,8 +1,5 @@ package app; -import javax.swing.JFrame; -import javax.swing.WindowConstants; - import data_access.ChessDataAccessObject; import entity.Board; import entity.Game; @@ -15,7 +12,7 @@ import view.ChessBoardView; /** - * Builder for the Note Application. + * Builder for the Chess Application. */ public class ChessAppBuilder { public static final int HEIGHT = 800; @@ -64,17 +61,7 @@ public ChessAppBuilder addMoveView() { return this; } - /** - * Builds the app. - * @return the JFrame for the app - */ - public JFrame build() { - final JFrame frame = new JFrame(); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - frame.setTitle("Chess App"); - frame.setSize(WIDTH, HEIGHT); - - frame.add(chessBoardView); - return frame; + public ChessBoardView buildChessBoardView() { + return chessBoardView; } } diff --git a/src/main/java/app/Main_ck.java b/src/main/java/app/MainChessAPP.java similarity index 96% rename from src/main/java/app/Main_ck.java rename to src/main/java/app/MainChessAPP.java index 463a744e7..35d3e5f60 100644 --- a/src/main/java/app/Main_ck.java +++ b/src/main/java/app/MainChessAPP.java @@ -18,7 +18,7 @@ /** * Main that activates login page. */ -public class Main_ck { +public class MainChessAPP { /** * The main method for starting the program with an external database used to persist user data. @@ -57,7 +57,7 @@ public static void main(String[] args) { views.add(loggedInView, loggedInView.getViewName()); views.add(profileView, profileView.getViewName()); - final CK_ChessAppBuilder chessAppBuilder = new CK_ChessAppBuilder(); + final ChessAppBuilder chessAppBuilder = new ChessAppBuilder(); chessAppBuilder.addChessDAO(new ChessDataAccessObject()) .addMoveView() .addMoveUseCase(); diff --git a/src/main/java/app/MainChessApp.java b/src/main/java/app/MainChessApp.java deleted file mode 100644 index 54aa50c4e..000000000 --- a/src/main/java/app/MainChessApp.java +++ /dev/null @@ -1,25 +0,0 @@ -package app; - -import data_access.ChessDataAccessObject; - -/** - * This is the main chess app. - */ -public class MainChessApp { - - /** - * Main method. - * @param args commandline arguments - */ - public static void main(String[] args) { - - // TODO change to ChessDataAccessInterface once implemented - final ChessDataAccessObject chessDataAccessObject = new ChessDataAccessObject(); - - final ChessAppBuilder chessAppBuilder = new ChessAppBuilder(); - chessAppBuilder.addChessDAO(chessDataAccessObject) - .addMoveView() - .addMoveUseCase().build().setVisible(true); - - } -} diff --git a/src/main/java/app/MainNoteApplication.java b/src/main/java/app/MainNoteApplication.java deleted file mode 100644 index c37860156..000000000 --- a/src/main/java/app/MainNoteApplication.java +++ /dev/null @@ -1,56 +0,0 @@ -package app; - -import data_access.DBNoteDataAccessObject; -import use_case.note.NoteDataAccessInterface; - -/** - * An application where we can view and add to a note stored by a user. - *

- * This is a minimal example of using the password-protected user API from lab 5, - * but demonstrating the endpoint allowing you to store an arbitrary JSON object. - * This functionality could be used in any project where your team wants to persist - * data which is then accessible across devices.

- *

The code is intentionally somewhat incomplete to leave work to be done if your - * team were to choose to work on a project which would require similar functionality. - * For example, we have intentionally not created a full "Note" entity here, but - * rather just represented a note as a string. - *

- * The ViewManager code has also been removed, since this minimal program only requires a single - * view. Your team may wish to bring back the ViewManager or make your own implementation of supporting - * switching between views depending on your project. - */ -public class MainNoteApplication { - - /** - * The main entry point of the application. - *

- * The program will show you the note currently saved in the system. - * You are able to edit it and then save it to the system. You can refresh - * to update the note to reflect what was saved most recently. This - * uses the API from lab, so there is one database storing the note, - * which means that if anyone updates the note, that is what you will - * see when you refresh. - *

- * You can generalize the code to allow you to - * specify which "user" to save the note for, which will allow your team - * to store information specific to your team which is password-protected. - * The username and password used in this application are currently for - * user jonathan_calver2, but you can change that. As you did in lab 3, - * you will likely want to store password information locally rather than - * in your repo. Or you can require the user to enter their credentials - * in your application; it just depends on what your program's main - * functionality. - *

- * @param args commandline arguments are ignored - */ - public static void main(String[] args) { - - // create the data access and inject it into our builder! - final NoteDataAccessInterface noteDataAccess = new DBNoteDataAccessObject(); - - final NoteAppBuilder builder = new NoteAppBuilder(); - builder.addNoteDAO(noteDataAccess) - .addNoteView() - .addNoteUseCase().build().setVisible(true); - } -} diff --git a/src/main/java/app/NoteAppBuilder.java b/src/main/java/app/NoteAppBuilder.java deleted file mode 100644 index a68cb9ad6..000000000 --- a/src/main/java/app/NoteAppBuilder.java +++ /dev/null @@ -1,83 +0,0 @@ -package app; - -import javax.swing.JFrame; -import javax.swing.WindowConstants; - -import interface_adapter.note.NoteController; -import interface_adapter.note.NotePresenter; -import interface_adapter.note.NoteViewModel; -import use_case.note.NoteDataAccessInterface; -import use_case.note.NoteInteractor; -import use_case.note.NoteOutputBoundary; -import view.NoteView; - -/** - * Builder for the Note Application. - */ -public class NoteAppBuilder { - public static final int HEIGHT = 300; - public static final int WIDTH = 400; - private NoteDataAccessInterface noteDAO; - private NoteViewModel noteViewModel = new NoteViewModel(); - private NoteView noteView; - private NoteInteractor noteInteractor; - - /** - * Sets the NoteDAO to be used in this application. - * @param noteDataAccess the DAO to use - * @return this builder - */ - public NoteAppBuilder addNoteDAO(NoteDataAccessInterface noteDataAccess) { - noteDAO = noteDataAccess; - return this; - } - - /** - * Creates the objects for the Note Use Case and connects the NoteView to its - * controller. - *

This method must be called after addNoteView!

- * @return this builder - * @throws RuntimeException if this method is called before addNoteView - */ - public NoteAppBuilder addNoteUseCase() { - final NoteOutputBoundary noteOutputBoundary = new NotePresenter(noteViewModel); - noteInteractor = new NoteInteractor( - noteDAO, noteOutputBoundary); - - final NoteController controller = new NoteController(noteInteractor); - if (noteView == null) { - throw new RuntimeException("addNoteView must be called before addNoteUseCase"); - } - noteView.setNoteController(controller); - return this; - } - - /** - * Creates the NoteView and underlying NoteViewModel. - * @return this builder - */ - public NoteAppBuilder addNoteView() { - noteViewModel = new NoteViewModel(); - noteView = new NoteView(noteViewModel); - return this; - } - - /** - * Builds the application. - * @return the JFrame for the application - */ - public JFrame build() { - final JFrame frame = new JFrame(); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - frame.setTitle("Note Application"); - frame.setSize(WIDTH, HEIGHT); - - frame.add(noteView); - - // refresh so that the note will be visible when we start the program - noteInteractor.executeRefresh(); - - return frame; - - } -} diff --git a/src/main/java/data_access/DBNoteDataAccessObject.java b/src/main/java/data_access/DBNoteDataAccessObject.java deleted file mode 100644 index dadb0cab0..000000000 --- a/src/main/java/data_access/DBNoteDataAccessObject.java +++ /dev/null @@ -1,107 +0,0 @@ -package data_access; - -import java.io.IOException; - -import org.json.JSONException; -import org.json.JSONObject; - -import entity.User; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; -import use_case.note.DataAccessException; -import use_case.note.NoteDataAccessInterface; - -/** - * The DAO for accessing notes stored in the database. - *

This class demonstrates how your group can use the password-protected user - * endpoints of the API used in lab 5 to store persistent data in your program. - *

- *

You can also refer to the lab 5 code for signing up a new user and other use cases. - *

- * See - * - * the documentation - * of the API for more details. - */ -public class DBNoteDataAccessObject implements NoteDataAccessInterface { - private static final int SUCCESS_CODE = 200; - private static final int CREDENTIAL_ERROR = 401; - private static final String CONTENT_TYPE_LABEL = "Content-Type"; - private static final String CONTENT_TYPE_JSON = "application/json"; - private static final String STATUS_CODE_LABEL = "status_code"; - private static final String USERNAME = "username"; - private static final String PASSWORD = "password"; - private static final String MESSAGE = "message"; - - @Override - public String saveNote(User user, String note) throws DataAccessException { - final OkHttpClient client = new OkHttpClient().newBuilder() - .build(); - - // POST METHOD - final MediaType mediaType = MediaType.parse(CONTENT_TYPE_JSON); - final JSONObject requestBody = new JSONObject(); - requestBody.put(USERNAME, user.getName()); - requestBody.put(PASSWORD, user.getPassword()); - final JSONObject extra = new JSONObject(); - extra.put("note", note); - requestBody.put("info", extra); - final RequestBody body = RequestBody.create(requestBody.toString(), mediaType); - final Request request = new Request.Builder() - .url("http://vm003.teach.cs.toronto.edu:20112/modifyUserInfo") - .method("PUT", body) - .addHeader(CONTENT_TYPE_LABEL, CONTENT_TYPE_JSON) - .build(); - try { - final Response response = client.newCall(request).execute(); - - final JSONObject responseBody = new JSONObject(response.body().string()); - - if (responseBody.getInt(STATUS_CODE_LABEL) == SUCCESS_CODE) { - return loadNote(user); - } - else if (responseBody.getInt(STATUS_CODE_LABEL) == CREDENTIAL_ERROR) { - throw new DataAccessException("message could not be found or password was incorrect"); - } - else { - throw new DataAccessException("database error: " + responseBody.getString(MESSAGE)); - } - } - catch (IOException | JSONException ex) { - throw new DataAccessException(ex.getMessage()); - } - } - - @Override - public String loadNote(User user) throws DataAccessException { - // Make an API call to get the user object. - final String username = user.getName(); - final OkHttpClient client = new OkHttpClient().newBuilder().build(); - final Request request = new Request.Builder() - .url(String.format("http://vm003.teach.cs.toronto.edu:20112/user?username=%s", username)) - .addHeader("Content-Type", CONTENT_TYPE_JSON) - .build(); - try { - final Response response = client.newCall(request).execute(); - - final JSONObject responseBody = new JSONObject(response.body().string()); - - if (responseBody.getInt(STATUS_CODE_LABEL) == SUCCESS_CODE) { - final JSONObject userJSONObject = responseBody.getJSONObject("user"); - final JSONObject data = userJSONObject.getJSONObject("info"); - return data.getString("note"); - } - else { - throw new DataAccessException(responseBody.getString(MESSAGE)); - } - } - catch (IOException | JSONException ex) { - throw new RuntimeException(ex); - } - } -} diff --git a/src/main/java/interface_adapter/note/NoteController.java b/src/main/java/interface_adapter/note/NoteController.java deleted file mode 100644 index e3e5dfb32..000000000 --- a/src/main/java/interface_adapter/note/NoteController.java +++ /dev/null @@ -1,28 +0,0 @@ -package interface_adapter.note; - -import use_case.note.NoteInputBoundary; - -/** - * Controller for our Note related Use Cases. - */ -public class NoteController { - - private final NoteInputBoundary noteInteractor; - - public NoteController(NoteInputBoundary noteInteractor) { - this.noteInteractor = noteInteractor; - } - - /** - * Executes the Note related Use Cases. - * @param note the note to be recorded - */ - public void execute(String note) { - if (note != null) { - noteInteractor.executeSave(note); - } - else { - noteInteractor.executeRefresh(); - } - } -} diff --git a/src/main/java/interface_adapter/note/NotePresenter.java b/src/main/java/interface_adapter/note/NotePresenter.java deleted file mode 100644 index d4e416165..000000000 --- a/src/main/java/interface_adapter/note/NotePresenter.java +++ /dev/null @@ -1,38 +0,0 @@ -package interface_adapter.note; - -import use_case.note.NoteOutputBoundary; - -/** - * The presenter for our Note viewing and editing program. - */ -public class NotePresenter implements NoteOutputBoundary { - - private final NoteViewModel noteViewModel; - - public NotePresenter(NoteViewModel noteViewModel) { - this.noteViewModel = noteViewModel; - } - - /** - * Prepares the success view for the Note related Use Cases. - * - * @param note the output data - */ - @Override - public void prepareSuccessView(String note) { - noteViewModel.getState().setNote(note); - noteViewModel.getState().setError(null); - noteViewModel.firePropertyChanged(); - } - - /** - * Prepares the failure view for the Note related Use Cases. - * - * @param errorMessage the explanation of the failure - */ - @Override - public void prepareFailView(String errorMessage) { - noteViewModel.getState().setError(errorMessage); - noteViewModel.firePropertyChanged(); - } -} diff --git a/src/main/java/interface_adapter/note/NoteState.java b/src/main/java/interface_adapter/note/NoteState.java deleted file mode 100644 index c5b2234d6..000000000 --- a/src/main/java/interface_adapter/note/NoteState.java +++ /dev/null @@ -1,26 +0,0 @@ -package interface_adapter.note; - -/** - * The State for a note. - *

For this example, a note is simplay a string.

- */ -public class NoteState { - private String note = ""; - private String error; - - public String getNote() { - return note; - } - - public void setNote(String note) { - this.note = note; - } - - public void setError(String errorMessage) { - this.error = errorMessage; - } - - public String getError() { - return error; - } -} diff --git a/src/main/java/interface_adapter/note/NoteViewModel.java b/src/main/java/interface_adapter/note/NoteViewModel.java deleted file mode 100644 index 6e185d0fa..000000000 --- a/src/main/java/interface_adapter/note/NoteViewModel.java +++ /dev/null @@ -1,13 +0,0 @@ -package interface_adapter.note; - -import interface_adapter.ViewModel; - -/** - * The ViewModel for the NoteView. - */ -public class NoteViewModel extends ViewModel { - public NoteViewModel() { - super("note"); - setState(new NoteState()); - } -} diff --git a/src/main/java/use_case/note/DataAccessException.java b/src/main/java/use_case/note/DataAccessException.java deleted file mode 100644 index b8c17920d..000000000 --- a/src/main/java/use_case/note/DataAccessException.java +++ /dev/null @@ -1,10 +0,0 @@ -package use_case.note; - -/** - * Exception thrown when there is an error with accessing data. - */ -public class DataAccessException extends Exception { - public DataAccessException(String string) { - super(string); - } -} diff --git a/src/main/java/use_case/note/NoteDataAccessInterface.java b/src/main/java/use_case/note/NoteDataAccessInterface.java deleted file mode 100644 index b71597828..000000000 --- a/src/main/java/use_case/note/NoteDataAccessInterface.java +++ /dev/null @@ -1,30 +0,0 @@ -package use_case.note; - -import entity.User; - -/** - * Interface for the NoteDAO. It consists of methods for - * both loading and saving a note. - */ -public interface NoteDataAccessInterface { - - /** - * Saves a note for a given user. This will replace any existing note. - *

The password of the user must match that of the user saved in the system.

- * @param user the user information associated with the note - * @param note the note to be saved - * @return the contents of the note - * @throws DataAccessException if the user's note can not be saved for any reason - */ - String saveNote(User user, String note) throws DataAccessException; - - /** - * Returns the note associated with the user. The password - * is not checked, so anyone can read the information. - * @param user the user information associated with the note - * @return the contents of the note - * @throws DataAccessException if the user's note can not be loaded for any reason - */ - String loadNote(User user) throws DataAccessException; - -} diff --git a/src/main/java/use_case/note/NoteInputBoundary.java b/src/main/java/use_case/note/NoteInputBoundary.java deleted file mode 100644 index b41da9bf5..000000000 --- a/src/main/java/use_case/note/NoteInputBoundary.java +++ /dev/null @@ -1,19 +0,0 @@ -package use_case.note; - -/** - * The Input Boundary for our note-related use cases. Since they are closely related, - * we have included them both in the same interface for simplicity. - */ -public interface NoteInputBoundary { - - /** - * Executes the refresh note use case. - */ - void executeRefresh(); - - /** - * Executes the save note use case. - * @param message the input data - */ - void executeSave(String message); -} diff --git a/src/main/java/use_case/note/NoteInteractor.java b/src/main/java/use_case/note/NoteInteractor.java deleted file mode 100644 index 369e9309a..000000000 --- a/src/main/java/use_case/note/NoteInteractor.java +++ /dev/null @@ -1,59 +0,0 @@ -package use_case.note; - -import entity.User; - -/** - * The "Use Case Interactor" for our two note-related use cases of refreshing - * the contents of the note and saving the contents of the note. Since they - * are closely related, we have combined them here for simplicity. - */ -public class NoteInteractor implements NoteInputBoundary { - - private final NoteDataAccessInterface noteDataAccessInterface; - private final NoteOutputBoundary noteOutputBoundary; - // Note: this program has it hardcoded which user object it is getting data for; - // you could change this if you wanted to generalize the code. For example, - // you might allow a user of the program to create a new note, which you - // could store as a "user" through the API OR you might maintain all notes - // in a JSON object stored in one common "user" stored through the API. - private final User user = new User("jonathan_calver2", "abc123"); - - public NoteInteractor(NoteDataAccessInterface noteDataAccessInterface, - NoteOutputBoundary noteOutputBoundary) { - this.noteDataAccessInterface = noteDataAccessInterface; - this.noteOutputBoundary = noteOutputBoundary; - } - - /** - * Executes the refresh note use case. - * - */ - @Override - public void executeRefresh() { - try { - - final String note = noteDataAccessInterface.loadNote(user); - noteOutputBoundary.prepareSuccessView(note); - } - catch (DataAccessException ex) { - noteOutputBoundary.prepareFailView(ex.getMessage()); - } - } - - /** - * Executes the save note use case. - * - * @param note the input data - */ - @Override - public void executeSave(String note) { - try { - - final String updatedNote = noteDataAccessInterface.saveNote(user, note); - noteOutputBoundary.prepareSuccessView(updatedNote); - } - catch (DataAccessException ex) { - noteOutputBoundary.prepareFailView(ex.getMessage()); - } - } -} diff --git a/src/main/java/use_case/note/NoteOutputBoundary.java b/src/main/java/use_case/note/NoteOutputBoundary.java deleted file mode 100644 index c0c2bb1d0..000000000 --- a/src/main/java/use_case/note/NoteOutputBoundary.java +++ /dev/null @@ -1,18 +0,0 @@ -package use_case.note; - -/** - * The output boundary for the Login Use Case. - */ -public interface NoteOutputBoundary { - /** - * Prepares the success view for the Note related Use Cases. - * @param message the output data - */ - void prepareSuccessView(String message); - - /** - * Prepares the failure view for the Note related Use Cases. - * @param errorMessage the explanation of the failure - */ - void prepareFailView(String errorMessage); -} diff --git a/src/main/java/view/NoteView.java b/src/main/java/view/NoteView.java deleted file mode 100644 index 331d76493..000000000 --- a/src/main/java/view/NoteView.java +++ /dev/null @@ -1,95 +0,0 @@ -package view; - -import java.awt.Component; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; - -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JTextArea; - -import interface_adapter.note.NoteController; -import interface_adapter.note.NoteState; -import interface_adapter.note.NoteViewModel; - -/** - * The View for when the user is viewing a note in the program. - */ -public class NoteView extends JPanel implements ActionListener, PropertyChangeListener { - - private final NoteViewModel noteViewModel; - - private final JLabel noteName = new JLabel("note for jonathan_calver2"); - private final JTextArea noteInputField = new JTextArea(); - - private final JButton saveButton = new JButton("Save"); - private final JButton refreshButton = new JButton("Refresh"); - private NoteController noteController; - - public NoteView(NoteViewModel noteViewModel) { - - noteName.setAlignmentX(Component.CENTER_ALIGNMENT); - this.noteViewModel = noteViewModel; - this.noteViewModel.addPropertyChangeListener(this); - - final JPanel buttons = new JPanel(); - buttons.add(saveButton); - buttons.add(refreshButton); - - saveButton.addActionListener( - evt -> { - if (evt.getSource().equals(saveButton)) { - noteController.execute(noteInputField.getText()); - - } - } - ); - - refreshButton.addActionListener( - evt -> { - if (evt.getSource().equals(refreshButton)) { - noteController.execute(null); - - } - } - ); - - this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - - this.add(noteName); - this.add(noteInputField); - this.add(buttons); - } - - /** - * React to a button click that results in evt. - * @param evt the ActionEvent to react to - */ - public void actionPerformed(ActionEvent evt) { - System.out.println("Click " + evt.getActionCommand()); - } - - @Override - public void propertyChange(PropertyChangeEvent evt) { - final NoteState state = (NoteState) evt.getNewValue(); - setFields(state); - if (state.getError() != null) { - JOptionPane.showMessageDialog(this, state.getError(), - "Error", JOptionPane.ERROR_MESSAGE); - } - } - - private void setFields(NoteState state) { - noteInputField.setText(state.getNote()); - } - - public void setNoteController(NoteController controller) { - this.noteController = controller; - } -} - From ea1f25d260ab644773c95aad536e56086fbfba37 Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Mon, 2 Dec 2024 16:32:46 -0500 Subject: [PATCH 080/125] delete 'note' test, modified 'ChessBoardViewTest' by create new 'testboard' and 'testgame' --- .../java/app/MainNoteApplicationTest.java | 112 ------------------ .../use_case/note/NoteInteractorTest.java | 46 ------- src/test/java/view/ChessBoardViewTest.java | 6 +- 3 files changed, 5 insertions(+), 159 deletions(-) delete mode 100644 src/test/java/app/MainNoteApplicationTest.java delete mode 100644 src/test/java/use_case/note/NoteInteractorTest.java diff --git a/src/test/java/app/MainNoteApplicationTest.java b/src/test/java/app/MainNoteApplicationTest.java deleted file mode 100644 index 025d970e2..000000000 --- a/src/test/java/app/MainNoteApplicationTest.java +++ /dev/null @@ -1,112 +0,0 @@ -package app; - -import entity.User; -import org.junit.Before; -import org.junit.Test; -import use_case.note.NoteDataAccessInterface; - -import javax.swing.*; -import java.awt.*; - -import static java.lang.Thread.sleep; -import static org.junit.Assert.*; - -public class MainNoteApplicationTest { - - private JFrame app; - - @Before - public void setUp() { - - // create the data access and inject it into our builder! - final NoteDataAccessInterface noteDataAccess = new NoteDataAccessInterface() { - - private String note = "test"; - - @Override - public String saveNote(User user, String note) { - this.note = note; - return note; - } - - @Override - public String loadNote(User user) { - return note; - } - }; - - final NoteAppBuilder builder = new NoteAppBuilder(); - app = builder.addNoteDAO(noteDataAccess) - .addNoteView() - .addNoteUseCase().build(); - - app.setVisible(true); - - } - - /** - * This is an example of an end-to-end test with a mocked database. - *

The code creates the application and directly tests to see that the GUI - * is updated as expected when the buttons and UI elements are interacted with. - *

- * You can run the test to visually see what happens. - */ - @Test - public void testEndToEnd() { - - Component[] components = ((JPanel)app.getRootPane().getContentPane().getComponents()[0]).getComponents(); - JTextArea textArea = null; - for (Component component : components) { - if (component instanceof JTextArea) { - textArea = (JTextArea) component; - assertEquals("test", textArea.getText()); - - } - } - - textArea.setText("test test"); - - - JButton save = null; - JButton load = null; - for (Component component : components) { - if (component instanceof JPanel) { - for (Component c : ((JPanel) component).getComponents()) { - if (c instanceof JButton) { - if (save != null) { - load = (JButton) c; - } - else { - save = (JButton) c; - } - } - } - } - } - - save.doClick(); - assertEquals("test test", textArea.getText()); - textArea.setText(""); - - System.out.println("cleared text; about to refresh..."); - // pause execution for a bit so we can visually see the changes on the screen - try { - sleep(1500); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - - load.doClick(); - assertEquals("test test", textArea.getText()); - - System.out.println("after refresh!"); - - // pause execution for a bit so we can visually see the changes on the screen - try { - sleep(1500); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - - } -} \ No newline at end of file diff --git a/src/test/java/use_case/note/NoteInteractorTest.java b/src/test/java/use_case/note/NoteInteractorTest.java deleted file mode 100644 index a3ed466b6..000000000 --- a/src/test/java/use_case/note/NoteInteractorTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package use_case.note; - -import entity.User; -import org.junit.Test; - -import static org.junit.Assert.*; - -public class NoteInteractorTest { - - @Test - public void testExecuteRefreshSuccess() { - - NoteDataAccessInterface noteDAO = new NoteDataAccessInterface() { - - - @Override - public String saveNote(User user, String note) { - return ""; - } - - - @Override - public String loadNote(User user) { - return "test"; - } - }; - - NoteOutputBoundary noteOB = new NoteOutputBoundary() { - @Override - public void prepareSuccessView(String message) { - assertEquals("test", message); - } - - @Override - public void prepareFailView(String errorMessage) { - fail(errorMessage); - } - }; - - NoteInteractor noteInteractor = new NoteInteractor(noteDAO, noteOB); - - noteInteractor.executeRefresh(); - - - } -} \ No newline at end of file diff --git a/src/test/java/view/ChessBoardViewTest.java b/src/test/java/view/ChessBoardViewTest.java index b100b4a9c..5186f0bdf 100644 --- a/src/test/java/view/ChessBoardViewTest.java +++ b/src/test/java/view/ChessBoardViewTest.java @@ -1,6 +1,8 @@ package view; import data_access.ChessDataAccessObject; +import entity.Board; +import entity.Game; import interface_adapter.ViewManagerModel; import interface_adapter.move.MoveController; import interface_adapter.move.MovePresenter; @@ -24,7 +26,9 @@ public static void main(String[] args) { MoveViewModel moveViewModel = new MoveViewModel(); ViewManagerModel viewManagerModel = new ViewManagerModel(); MoveOutputBoundary movePresenter = new MovePresenter(moveViewModel, viewManagerModel); - MoveInteractor TestInteractor = new MoveInteractor(moveDataAccessObject, movePresenter); + Board board = new Board(); + Game game = new Game(board, true); + MoveInteractor TestInteractor = new MoveInteractor(moveDataAccessObject, movePresenter, game); MoveController TestController = new MoveController(TestInteractor); ChessBoardView TestView = new ChessBoardView(TestModel, TestController); From 706394f114a41a241ee0af105db0b86c3d838c2a Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Mon, 2 Dec 2024 18:11:41 -0500 Subject: [PATCH 081/125] accessibility report added --- accessibility-report.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 accessibility-report.md diff --git a/accessibility-report.md b/accessibility-report.md new file mode 100644 index 000000000..70a3e6883 --- /dev/null +++ b/accessibility-report.md @@ -0,0 +1,22 @@ +## Principle of Universal desgin + ++ Equitable Use + + Users are allowed to input any String as their username, not restricted to english. User with none english name can benefit from this. ++ Flexibility in Use + + Features could add: Allowed user to pick board theme (ie., Black/white, light theme, dark theme). ++ Simple and Intuitive Use + + Move use are match with intuition. Click a piece to select, slick a grid to move ++ Perceptible Information + + This program can't accommodate user with visual disability currently. A potential feature might add to accommodate visual disability is allowed user to select other output device (ie., touch board) ++ Tolerance of Error + + Tolerating wrong click on grid that doesn't contain piece. Error message like "Can't select empty grid" doesn't sent, because click on empty grid is common that sent error message everytime wrong click happened will be annoyed. ++ Low Physical Effort + + The only interaction use need while play the chess game is clicking mose. ++ Size and Space for Approach and Use + + Size of the window (chess board) is adjustable. + +## Program Market ++ If I were to market my chess puzzle program, I would target chess enthusiasts and learners of all ages, particularly those seeking to improve their strategic thinking and problem-solving skills. The program would appeal to students and educators looking for engaging tools to teach or practice chess fundamentals, as well as casual players who enjoy the intellectual challenge of solving puzzles in their leisure time. Additionally, the program could attract competitive chess players aiming to refine their tactics through a curated collection of puzzles ranging from beginner to advanced levels. + +## People who can't take advantage of this App ++ People with dysgnosia is less likely to take advantage of this App, simply because this App is meant to be intellectually challenging. However, puzzle difficulty classification feature can be added and might accommodate people with dysgnosia. \ No newline at end of file From 7bd86079be0188218576ce5eea1919795c1ab0cf Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Mon, 2 Dec 2024 18:35:27 -0500 Subject: [PATCH 082/125] README update --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d64638d00..79cc9d3f5 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Note: No additional package needed -### Signup & Login +### Signup & Login This feature allows users to signup by creating username and password and login to the account created. @@ -56,7 +56,7 @@ To Signup: Enter username and password(two times) to be used for an account, and To Login: Click ```Login``` to navigate to a login page, enter username and password for the account, and click ```Login``` to confirm login. -### Show Profile +### Show Profile User can view there profile (Contain User name and rank point currently) after login by click ```Show Profile``` after login. @@ -65,11 +65,11 @@ Note: New user's rank point is set to ```0``` -### Generate daily puzzle +### Generate daily puzzle // TODO -### Step by step move +### Step by step move // TODO From a68e61ffd60c25e153e5d0e28cc789ebb552de25 Mon Sep 17 00:00:00 2001 From: jiaqi ma Date: Mon, 2 Dec 2024 20:18:54 -0500 Subject: [PATCH 083/125] remove highlighted grid when game just start, README link update --- README.md | 11 +++++++---- .../java/interface_adapter/move/MoveViewModel.java | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 79cc9d3f5..350038f3c 100644 --- a/README.md +++ b/README.md @@ -14,14 +14,17 @@ Yann Chi - YannChi22 ## Table of content -+ [Project Domain](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#project-domain) - -+ [Instructions](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#instructions) ++ [About This Project](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#about-this-project) ++ [Installation](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#installation) ++ [Use Case (Feature)](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#use-cases-features) + [Signup & Login](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#signup--login) + [Show Profile](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#show-profile) + [Generate Daily Puzzle](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#generate-daily-puzzle) + [Step by Step Move](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#generate-daily-puzzle) -+ [Use Cases](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#use-cases) ++ [Usage Guide](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#usage-guide) ++ [Feedback](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#feedback) ++ [Contribute to this project](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#this-project-is-close-for-contributions) ++ [User Stories](https://github.com/DDMMMAA/CSC207-Team179?tab=readme-ov-file#user-stories) ## About this project diff --git a/src/main/java/interface_adapter/move/MoveViewModel.java b/src/main/java/interface_adapter/move/MoveViewModel.java index fe0794167..04f3664a0 100644 --- a/src/main/java/interface_adapter/move/MoveViewModel.java +++ b/src/main/java/interface_adapter/move/MoveViewModel.java @@ -13,7 +13,7 @@ public class MoveViewModel extends ViewModel { private final String[][] pieces = { {"♜", "♞", "♝", "♛", "♚", "♝", "♞", "♜"}, // Black major pieces {"♟", "♟", "♟", "♟", "♟", "♟", "♟", "♟"}, // Black pawns - {null, null, null, null, null, null, null, "Valid"}, // Empty row with one Valid move + {null, null, null, null, null, null, null, null}, // Empty row with one Valid move {null, null, null, null, null, null, null, null}, // Empty row {null, null, null, null, null, null, null, null}, // Empty row {null, null, null, null, null, null, null, null}, // Empty row From 7b22b76ed5b660c60f132d7b59f8e26f7b106304 Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Mon, 2 Dec 2024 22:14:11 -0500 Subject: [PATCH 084/125] Delete cancel button --- src/main/java/interface_adapter/move/MovePresenter.java | 2 +- src/main/java/view/SignupView.java | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/java/interface_adapter/move/MovePresenter.java b/src/main/java/interface_adapter/move/MovePresenter.java index 90bce3733..2520b1284 100644 --- a/src/main/java/interface_adapter/move/MovePresenter.java +++ b/src/main/java/interface_adapter/move/MovePresenter.java @@ -1,7 +1,7 @@ package interface_adapter.move; //import chariot.model.MoveInfo; -import chariot.util.Board; +//import chariot.util.Board; import interface_adapter.ViewManagerModel; import use_case.move.MoveInputdata; import use_case.move.MoveOutputBoundary; diff --git a/src/main/java/view/SignupView.java b/src/main/java/view/SignupView.java index 5b34c8e83..01b9f5fb3 100644 --- a/src/main/java/view/SignupView.java +++ b/src/main/java/view/SignupView.java @@ -33,7 +33,6 @@ public class SignupView extends JPanel implements ActionListener, PropertyChange private final SignupController signupController; private final JButton signUp; - private final JButton cancel; private final JButton toLogin; public SignupView(SignupController controller, SignupViewModel signupViewModel) { @@ -57,8 +56,6 @@ public SignupView(SignupController controller, SignupViewModel signupViewModel) buttons.add(toLogin); signUp = new JButton(SignupViewModel.SIGNUP_BUTTON_LABEL); buttons.add(signUp); - cancel = new JButton(SignupViewModel.CANCEL_BUTTON_LABEL); - buttons.add(cancel); signUp.addActionListener( new ActionListener() { @@ -86,8 +83,6 @@ public void actionPerformed(ActionEvent evt) { } ); - cancel.addActionListener(this); - addUsernameListener(); addPasswordListener(); addRepeatPasswordListener(); From aae5772b95ffb5d02710f01b512379ad6daaae62 Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Mon, 2 Dec 2024 22:14:40 -0500 Subject: [PATCH 085/125] Delete unused line --- src/main/java/app/MainChessAPP.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/app/MainChessAPP.java b/src/main/java/app/MainChessAPP.java index 35d3e5f60..f274ae08a 100644 --- a/src/main/java/app/MainChessAPP.java +++ b/src/main/java/app/MainChessAPP.java @@ -50,7 +50,6 @@ public static void main(String[] args) { final LoggedInView loggedInView = ShowProfileUseCaseFactory.create(viewManagerModel, loggedInViewModel, signupViewModel, showProfileViewModel, userDataAccessObject); final ProfileView profileView = new ProfileView(viewManagerModel, showProfileViewModel); - // final LoggedInView loggedInView = new LoggedInView(viewManagerModel, loggedInViewModel); views.add(signupView, signupView.getViewName()); views.add(loginView, loginView.getViewName()); From 76b913b46e140b36dc410be2049a8b9867863722 Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Mon, 2 Dec 2024 22:53:32 -0500 Subject: [PATCH 086/125] checkstyle --- src/main/java/app/ShowProfileUseCaseFactory.java | 6 +++--- src/main/java/view/LoggedInView.java | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/app/ShowProfileUseCaseFactory.java b/src/main/java/app/ShowProfileUseCaseFactory.java index 319d7f9dc..039b466ec 100644 --- a/src/main/java/app/ShowProfileUseCaseFactory.java +++ b/src/main/java/app/ShowProfileUseCaseFactory.java @@ -32,8 +32,8 @@ private ShowProfileUseCaseFactory() { * * @param viewManagerModel the ViewManagerModel to inject into the LoggedInView * @param loggedInViewModel the loggedInViewModel to inject into the LoggedInView - * @param signupViewModel - * @param showProfileViewModel + * @param signupViewModel the signupViewModel + * @param showProfileViewModel the showProfileViewModel * @param userDataAccessObject the ChangePasswordUserDataAccessInterface to inject into the LoggedInView * @return the LoggedInView created for the provided input classes */ @@ -72,7 +72,7 @@ private static ShowProfileController createShowProfileUseCase( private static LoggedInController createLoggedInUseCase( ViewManagerModel viewManagerModel, LoggedInViewModel loggedInViewModel, - SignupViewModel signupViewModel){ + SignupViewModel signupViewModel) { final LoggedInOutputBoundary loggedInOutputBoundary = new LoggedInPresenter(viewManagerModel, loggedInViewModel, signupViewModel); diff --git a/src/main/java/view/LoggedInView.java b/src/main/java/view/LoggedInView.java index 811a03336..f0af5108a 100644 --- a/src/main/java/view/LoggedInView.java +++ b/src/main/java/view/LoggedInView.java @@ -58,8 +58,6 @@ public LoggedInView(ViewManagerModel viewManagerModel, LoggedInController logged startChess = new JButton("Start Chess Game"); buttons.add(startChess); -// logOut.addActionListener(this); - logOut.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { From 8b6b4b843a1ecb35ebd3689004f5466e01928d4e Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Mon, 2 Dec 2024 23:19:39 -0500 Subject: [PATCH 087/125] Create the functionality of cancel button at Login page --- src/main/java/app/LoginUseCaseFactory.java | 12 +++++++----- src/main/java/app/MainChessAPP.java | 2 +- .../logged_in/LoggedInController.java | 2 +- .../interface_adapter/login/LoginController.java | 7 +++++++ .../java/interface_adapter/login/LoginPresenter.java | 12 +++++++++++- .../use_case/logged_in/LoggedInInputBoundary.java | 2 +- src/main/java/use_case/login/LoginInputBoundary.java | 5 +++++ src/main/java/use_case/login/LoginInteractor.java | 5 +++++ .../java/use_case/login/LoginOutputBoundary.java | 6 ++++++ src/main/java/view/LoginView.java | 12 +++++++++++- 10 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/main/java/app/LoginUseCaseFactory.java b/src/main/java/app/LoginUseCaseFactory.java index 4685a7c69..daa4ef2ac 100644 --- a/src/main/java/app/LoginUseCaseFactory.java +++ b/src/main/java/app/LoginUseCaseFactory.java @@ -5,6 +5,7 @@ import interface_adapter.login.LoginController; import interface_adapter.login.LoginPresenter; import interface_adapter.login.LoginViewModel; +import interface_adapter.signup.SignupViewModel; import use_case.login.LoginInputBoundary; import use_case.login.LoginInteractor; import use_case.login.LoginOutputBoundary; @@ -33,10 +34,11 @@ public static LoginView create( ViewManagerModel viewManagerModel, LoginViewModel loginViewModel, LoggedInViewModel loggedInViewModel, - LoginUserDataAccessInterface userDataAccessObject) { + LoginUserDataAccessInterface userDataAccessObject, + SignupViewModel signupViewModel) { final LoginController loginController = createLoginUseCase(viewManagerModel, loginViewModel, - loggedInViewModel, userDataAccessObject); + loggedInViewModel, userDataAccessObject, signupViewModel); return new LoginView(loginViewModel, loginController); } @@ -45,11 +47,11 @@ private static LoginController createLoginUseCase( ViewManagerModel viewManagerModel, LoginViewModel loginViewModel, LoggedInViewModel loggedInViewModel, - LoginUserDataAccessInterface userDataAccessObject) { + LoginUserDataAccessInterface userDataAccessObject, + SignupViewModel signupViewModel) { - // Notice how we pass this method's parameters to the Presenter. final LoginOutputBoundary loginOutputBoundary = new LoginPresenter(viewManagerModel, - loggedInViewModel, loginViewModel); + loggedInViewModel, loginViewModel, signupViewModel); final LoginInputBoundary loginInteractor = new LoginInteractor( userDataAccessObject, loginOutputBoundary); diff --git a/src/main/java/app/MainChessAPP.java b/src/main/java/app/MainChessAPP.java index f274ae08a..f338a9fd7 100644 --- a/src/main/java/app/MainChessAPP.java +++ b/src/main/java/app/MainChessAPP.java @@ -46,7 +46,7 @@ public static void main(String[] args) { final SignupView signupView = SignupUseCaseFactory.create(viewManagerModel, loginViewModel, signupViewModel, userDataAccessObject); final LoginView loginView = LoginUseCaseFactory.create(viewManagerModel, loginViewModel, - loggedInViewModel, userDataAccessObject); + loggedInViewModel, userDataAccessObject, signupViewModel); final LoggedInView loggedInView = ShowProfileUseCaseFactory.create(viewManagerModel, loggedInViewModel, signupViewModel, showProfileViewModel, userDataAccessObject); final ProfileView profileView = new ProfileView(viewManagerModel, showProfileViewModel); diff --git a/src/main/java/interface_adapter/logged_in/LoggedInController.java b/src/main/java/interface_adapter/logged_in/LoggedInController.java index 3f214dde7..6169be369 100644 --- a/src/main/java/interface_adapter/logged_in/LoggedInController.java +++ b/src/main/java/interface_adapter/logged_in/LoggedInController.java @@ -14,7 +14,7 @@ public LoggedInController(LoggedInInputBoundary userLoggedInUseCaseInteractor) { } /** - * Executes the "switch to LoginView" Use Case. + * Executes the "switch to SignUpView" Use Case. */ public void switchToSignUpView() { userLoggedInUseCaseInteractor.switchToSignUpView(); diff --git a/src/main/java/interface_adapter/login/LoginController.java b/src/main/java/interface_adapter/login/LoginController.java index 57e950666..5ec3363ee 100644 --- a/src/main/java/interface_adapter/login/LoginController.java +++ b/src/main/java/interface_adapter/login/LoginController.java @@ -25,4 +25,11 @@ public void execute(String username, String password) { loginUseCaseInteractor.execute(loginInputData); } + + /** + * Executes the "switch to SignUpView" Use Case. + */ + public void switchToSignUpView() { + loginUseCaseInteractor.switchToSignUpView(); + } } diff --git a/src/main/java/interface_adapter/login/LoginPresenter.java b/src/main/java/interface_adapter/login/LoginPresenter.java index 087996fd2..3b0ff9e0e 100644 --- a/src/main/java/interface_adapter/login/LoginPresenter.java +++ b/src/main/java/interface_adapter/login/LoginPresenter.java @@ -3,6 +3,7 @@ import interface_adapter.ViewManagerModel; import interface_adapter.logged_in.LoggedInState; import interface_adapter.logged_in.LoggedInViewModel; +import interface_adapter.signup.SignupViewModel; import use_case.login.LoginOutputBoundary; import use_case.login.LoginOutputData; @@ -14,13 +15,16 @@ public class LoginPresenter implements LoginOutputBoundary { private final LoginViewModel loginViewModel; private final LoggedInViewModel loggedInViewModel; private final ViewManagerModel viewManagerModel; + private final SignupViewModel signupViewModel; public LoginPresenter(ViewManagerModel viewManagerModel, LoggedInViewModel loggedInViewModel, - LoginViewModel loginViewModel) { + LoginViewModel loginViewModel, + SignupViewModel signupViewModel) { this.viewManagerModel = viewManagerModel; this.loggedInViewModel = loggedInViewModel; this.loginViewModel = loginViewModel; + this.signupViewModel = signupViewModel; } @Override @@ -42,4 +46,10 @@ public void prepareFailView(String error) { loginState.setLoginError(error); loginViewModel.firePropertyChanged(); } + + @Override + public void switchToSignUpView() { + viewManagerModel.setState(signupViewModel.getViewName()); + viewManagerModel.firePropertyChanged(); + } } diff --git a/src/main/java/use_case/logged_in/LoggedInInputBoundary.java b/src/main/java/use_case/logged_in/LoggedInInputBoundary.java index 6f0931f78..67659dd5e 100644 --- a/src/main/java/use_case/logged_in/LoggedInInputBoundary.java +++ b/src/main/java/use_case/logged_in/LoggedInInputBoundary.java @@ -5,7 +5,7 @@ */ public interface LoggedInInputBoundary { /** - * Executes the switch to login view use case. + * Executes the switch to signup view use case. */ void switchToSignUpView(); } diff --git a/src/main/java/use_case/login/LoginInputBoundary.java b/src/main/java/use_case/login/LoginInputBoundary.java index 0b59f2a4f..35d3bf853 100644 --- a/src/main/java/use_case/login/LoginInputBoundary.java +++ b/src/main/java/use_case/login/LoginInputBoundary.java @@ -9,4 +9,9 @@ public interface LoginInputBoundary { * @param loginInputData the input data */ void execute(LoginInputData loginInputData); + + /** + * Executes the switch to signup view use case. + */ + void switchToSignUpView(); } diff --git a/src/main/java/use_case/login/LoginInteractor.java b/src/main/java/use_case/login/LoginInteractor.java index 2ed57f690..9d04c3692 100644 --- a/src/main/java/use_case/login/LoginInteractor.java +++ b/src/main/java/use_case/login/LoginInteractor.java @@ -36,4 +36,9 @@ public void execute(LoginInputData loginInputData) { } } } + + @Override + public void switchToSignUpView() { + loginPresenter.switchToSignUpView(); + } } diff --git a/src/main/java/use_case/login/LoginOutputBoundary.java b/src/main/java/use_case/login/LoginOutputBoundary.java index c835b4bc0..f926e7785 100644 --- a/src/main/java/use_case/login/LoginOutputBoundary.java +++ b/src/main/java/use_case/login/LoginOutputBoundary.java @@ -9,9 +9,15 @@ public interface LoginOutputBoundary { * @param outputData the output data */ void prepareSuccessView(LoginOutputData outputData); + /** * Prepares the failure view for the Login Use Case. * @param errorMessage the explanation of the failure */ void prepareFailView(String errorMessage); + + /** + * Switches to the Signup View. + */ + void switchToSignUpView(); } diff --git a/src/main/java/view/LoginView.java b/src/main/java/view/LoginView.java index 68dea9ab5..473fb9084 100644 --- a/src/main/java/view/LoginView.java +++ b/src/main/java/view/LoginView.java @@ -72,7 +72,17 @@ public void actionPerformed(ActionEvent evt) { } ); - cancel.addActionListener(this); + //cancel.addActionListener(this); + + cancel.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(cancel)) { + loginController.switchToSignUpView(); + } + } + } + ); usernameInputField.getDocument().addDocumentListener(new DocumentListener() { From 2460f70ca7c44f01bda93a349090ff0b652db4f1 Mon Sep 17 00:00:00 2001 From: J0hnDing Date: Mon, 2 Dec 2024 23:30:44 -0500 Subject: [PATCH 088/125] Valid moves and turn based game has been implemented. --- src/main/java/entity/Bishop.java | 41 +++-- src/main/java/entity/Board.java | 86 +++++++--- src/main/java/entity/ChessPiece.java | 13 +- src/main/java/entity/Game.java | 11 +- src/main/java/entity/King.java | 5 +- src/main/java/entity/Knight.java | 5 +- src/main/java/entity/Pawn.java | 16 +- src/main/java/entity/Queen.java | 81 +++++++++- src/main/java/entity/Rook.java | 29 +++- .../move/MoveController.java | 1 - .../interface_adapter/move/MovePresenter.java | 2 +- .../java/use_case/move/MoveInteractor.java | 151 ++++++++++++++++-- src/main/java/view/ChessBoardView.java | 3 +- 13 files changed, 356 insertions(+), 88 deletions(-) diff --git a/src/main/java/entity/Bishop.java b/src/main/java/entity/Bishop.java index 548429c93..ca54f1397 100644 --- a/src/main/java/entity/Bishop.java +++ b/src/main/java/entity/Bishop.java @@ -1,10 +1,14 @@ package entity; import java.util.ArrayList; +import java.util.Collections; +/** + * The bishop class. + */ public class Bishop extends ChessPiece { - public Bishop(String color, int x, int y) { - super(color, x, y); + public Bishop(String color, int xCoord, int yCoord) { + super(color, xCoord, yCoord); } /** @@ -12,38 +16,57 @@ public Bishop(String color, int x, int y) { * * @return A list of int arrays, each representing a valid move [newX, newY]. */ - public ArrayList getValidMoves() { - final ArrayList validMoves = new ArrayList<>(); + @SuppressWarnings({"unchecked", "checkstyle:MagicNumber", "checkstyle:SuppressWarnings"}) + @Override + public T getValidMoves() { + // Create an ArrayList to hold four ArrayLists (one for each direction) + final ArrayList> validMoves = new ArrayList<>(); + + // Initialize four ArrayLists for each diagonal direction + final ArrayList upLeft = new ArrayList<>(); + final ArrayList upRight = new ArrayList<>(); + final ArrayList downLeft = new ArrayList<>(); + final ArrayList downRight = new ArrayList<>(); + final int x = this.getPosition()[0]; final int y = this.getPosition()[1]; + // Up-Left Diagonal int i = 1; while (x - i >= 0 && y - i >= 0) { - validMoves.add(new int[]{x - i, y - i}); + upLeft.add(0, new int[]{x - i, y - i}); i++; } // Up-Right Diagonal i = 1; while (x + i < 8 && y - i >= 0) { - validMoves.add(new int[]{x + i, y - i}); + upRight.add(0, new int[]{x + i, y - i}); i++; } // Down-Left Diagonal i = 1; while (x - i >= 0 && y + i < 8) { - validMoves.add(new int[]{x - i, y + i}); + downLeft.add(0, new int[]{x - i, y + i}); i++; } // Down-Right Diagonal i = 1; while (x + i < 8 && y + i < 8) { - validMoves.add(new int[]{x + i, y + i}); + downRight.add(0, new int[]{x + i, y + i}); i++; } + Collections.reverse(upLeft); + Collections.reverse(upRight); + Collections.reverse(downLeft); + Collections.reverse(downRight); + validMoves.add(upLeft); + validMoves.add(upRight); + validMoves.add(downLeft); + validMoves.add(downRight); - return validMoves; + return (T) validMoves; } } diff --git a/src/main/java/entity/Board.java b/src/main/java/entity/Board.java index 50ed58320..ecea5d3dd 100644 --- a/src/main/java/entity/Board.java +++ b/src/main/java/entity/Board.java @@ -8,40 +8,42 @@ public class Board { private ChessPiece[][] grid; + @SuppressWarnings("checkstyle:MagicNumber") public Board() { - ChessPiece[][] grid = new ChessPiece[8][8]; + final ChessPiece[][] chessGrid = new ChessPiece[8][8]; - grid[0][0] = new Rook("White", 0, 0); - grid[0][1] = new Knight("White", 0, 1); - grid[0][2] = new Bishop("White", 0, 2); - grid[0][3] = new Queen("White", 0, 3); - grid[0][4] = new King("White", 0, 4); - grid[0][5] = new Bishop("White", 0, 5); - grid[0][6] = new Knight("White", 0, 6); - grid[0][7] = new Rook("White", 0, 7); + final String white = "White"; + chessGrid[0][0] = new Rook(white, 0, 0); + chessGrid[0][1] = new Knight(white, 0, 1); + chessGrid[0][2] = new Bishop(white, 0, 2); + chessGrid[0][3] = new Queen(white, 0, 3); + chessGrid[0][4] = new King(white, 0, 4); + chessGrid[0][5] = new Bishop(white, 0, 5); + chessGrid[0][6] = new Knight(white, 0, 6); + chessGrid[0][7] = new Rook(white, 0, 7); for (int i = 0; i < 8; i++) { - grid[1][i] = new Pawn("White", 1, i); + chessGrid[1][i] = new Pawn(white, 1, i); } - grid[7][0] = new Rook("Black", 7, 0); - grid[7][1] = new Knight("Black", 7, 1); - grid[7][2] = new Bishop("Black", 7, 2); - grid[7][3] = new Queen("Black", 7, 3); - grid[7][4] = new King("Black", 7, 4); - grid[7][5] = new Bishop("Black", 7, 5); - grid[7][6] = new Knight("Black", 7, 6); - grid[7][7] = new Rook("Black", 7, 7); + final String black = "Black"; + chessGrid[7][0] = new Rook(black, 7, 0); + chessGrid[7][1] = new Knight(black, 7, 1); + chessGrid[7][2] = new Bishop(black, 7, 2); + chessGrid[7][3] = new Queen(black, 7, 3); + chessGrid[7][4] = new King(black, 7, 4); + chessGrid[7][5] = new Bishop(black, 7, 5); + chessGrid[7][6] = new Knight(black, 7, 6); + chessGrid[7][7] = new Rook(black, 7, 7); for (int i = 0; i < 8; i++) { - grid[6][i] = new Pawn("Black", 6, i); + chessGrid[6][i] = new Pawn(black, 6, i); } -// Set all empty squares to null for (int row = 2; row < 6; row++) { for (int col = 0; col < 8; col++) { - grid[row][col] = null; + chessGrid[row][col] = null; } } - this.grid = grid; + this.grid = chessGrid; } public Board(JSONObject boardFile) { @@ -50,6 +52,7 @@ public Board(JSONObject boardFile) { /** * Returns if a tile is empty. + * * @param position position of piece * @return bool */ @@ -59,6 +62,7 @@ public boolean isEmpty(int[] position) { /** * Returns the chess piece at a given tile. + * * @param position position of piece * @return Chesspiece */ @@ -66,11 +70,47 @@ public ChessPiece getPiece(int[] position) { return grid[position[0]][position[1]]; } - + /** + * Moves a piece to the specified position on the board. + * + * @param position The new position (x, y) for the piece. + * @param piece The piece to move. + */ public void moveToLocation(int[] position, ChessPiece piece) { grid[piece.getPosition()[0]][piece.getPosition()[1]] = null; piece.setPosition(position); grid[position[0]][position[1]] = piece; } + /** + * Checks if the game is over by determining if either king is missing. + * + * @return "None" if both kings are present, "Black" if the white king is missing, + * "White" if the black king is missing. + */ + public String over() { + boolean whiteKingPresent = false; + boolean blackKingPresent = false; + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 8; j++) { + if (grid[i][j] instanceof King) { + if (grid[i][j].getColor().equals("White")) { + whiteKingPresent = true; + } + else { + blackKingPresent = true; + } + } + } + } + if (whiteKingPresent && blackKingPresent) { + return "None"; + } + else if (whiteKingPresent) { + return "Black"; + } + else { + return "White"; + } + } } diff --git a/src/main/java/entity/ChessPiece.java b/src/main/java/entity/ChessPiece.java index 07a0d0575..b37995972 100644 --- a/src/main/java/entity/ChessPiece.java +++ b/src/main/java/entity/ChessPiece.java @@ -1,24 +1,26 @@ package entity; -import java.util.ArrayList; /** * The abstract class of all chess piece. */ +@SuppressWarnings({"checkstyle:AbstractClassName", "checkstyle:SuppressWarnings"}) public abstract class ChessPiece { private final String color; private int[] position; - public ChessPiece(String color, int x, int y) { + protected ChessPiece(String color, int xCoordinate, int yCoordinate) { this.color = color; this.position = new int[2]; - position[0] = x; - position[1] = y; + position[0] = xCoordinate; + position[1] = yCoordinate; } /** * The abstract class for getting the valid moves of a piece. + * @param type of return value. + * @return return a list of valid moves. */ - public abstract ArrayList getValidMoves(); + public abstract T getValidMoves(); public String getColor() { return color; @@ -27,6 +29,7 @@ public String getColor() { public int[] getPosition() { return this.position; } + public void setPosition(int[] position) { this.position = position; } diff --git a/src/main/java/entity/Game.java b/src/main/java/entity/Game.java index 08ce24135..37b3b2058 100644 --- a/src/main/java/entity/Game.java +++ b/src/main/java/entity/Game.java @@ -2,7 +2,6 @@ public class Game { private final Board board; - private final String currentPlayer; private boolean gameOver; private boolean whiteTurn; //if whiteturn is false, then its blacks turn private boolean selectMode; //if select mode is false, game is in movemode. @@ -10,7 +9,6 @@ public class Game { public Game(Board board, boolean whiteTurn) { this.board = board; - this.currentPlayer = null; this.gameOver = false; this.whiteTurn = whiteTurn; this.selectMode = true; @@ -26,13 +24,8 @@ public void switchTurn() { } } - public String getCurrentPlayer() { - if (currentPlayer == null) { - return "No Player Selected"; - } - else { - return currentPlayer; - } + public boolean getCurrentPlayer() { + return this.whiteTurn; } public ChessPiece getChesspiece_to_move() { diff --git a/src/main/java/entity/King.java b/src/main/java/entity/King.java index 3339619d8..b31ad099b 100644 --- a/src/main/java/entity/King.java +++ b/src/main/java/entity/King.java @@ -16,7 +16,8 @@ public King(String color, int x, int y) { * * @return A list of int arrays, each representing a valid move [newX, newY]. */ - public ArrayList getValidMoves() { + @Override + public T getValidMoves() { final ArrayList validMoves = new ArrayList<>(); final int x = this.getPosition()[0]; final int y = this.getPosition()[1]; @@ -25,7 +26,7 @@ public ArrayList getValidMoves() { validMoves.add(new int[]{x, y - 1}); validMoves.add(new int[]{x, y + 1}); validMoves.removeIf(move -> move[0] < 0 || move[0] >= 8 || move[1] < 0 || move[1] >= 8); - return validMoves; + return (T) validMoves; } } diff --git a/src/main/java/entity/Knight.java b/src/main/java/entity/Knight.java index 48f5350a5..8194c44c4 100644 --- a/src/main/java/entity/Knight.java +++ b/src/main/java/entity/Knight.java @@ -16,7 +16,8 @@ public Knight(String color, int x, int y) { * * @return A list of int arrays, each representing a valid move [newX, newY]. */ - public ArrayList getValidMoves() { + @Override + public T getValidMoves() { final ArrayList validMoves = new ArrayList<>(); final int x = this.getPosition()[0]; final int y = this.getPosition()[1]; @@ -35,6 +36,6 @@ public ArrayList getValidMoves() { } } - return validMoves; + return (T) validMoves; } } diff --git a/src/main/java/entity/Pawn.java b/src/main/java/entity/Pawn.java index 971d52910..e0bdea624 100644 --- a/src/main/java/entity/Pawn.java +++ b/src/main/java/entity/Pawn.java @@ -11,22 +11,28 @@ public Pawn(String color, int x, int y) { * Returns all possible moves for a pawn from the given position on an 8x8 chessboard. * @return A list of int arrays, each representing a valid move [newX, newY]. */ - public ArrayList getValidMoves() { + @Override + public T getValidMoves() { final ArrayList validMoves = new ArrayList<>(); final int x = this.getPosition()[0]; final int y = this.getPosition()[1]; if (this.getColor().equals("White") && x != 7) { - validMoves.add(new int[]{x + 1, y + 1}); validMoves.add(new int[]{x + 1, y - 1}); + validMoves.add(new int[]{x + 1, y + 1}); validMoves.add(new int[]{x + 1, y}); + if (x == 1) { + validMoves.add(new int[]{x + 2, y}); + } } else if (this.getColor().equals("Black") && x != 0) { validMoves.add(new int[]{x - 1, y - 1}); - validMoves.add(new int[]{x - 1, y }); validMoves.add(new int[]{x - 1, y + 1}); + validMoves.add(new int[]{x - 1, y}); + if (x == 6) { + validMoves.add(new int[]{x - 2, y}); + } } - validMoves.removeIf(move -> move[0] < 0 || move[1] < 0 || move[0] > 7 || move[1] > 7); - return validMoves; + return (T) validMoves; } } diff --git a/src/main/java/entity/Queen.java b/src/main/java/entity/Queen.java index 42949203b..90e0f8cfe 100644 --- a/src/main/java/entity/Queen.java +++ b/src/main/java/entity/Queen.java @@ -1,7 +1,11 @@ package entity; import java.util.ArrayList; +import java.util.Collections; +/** + * Queen Class. + */ public class Queen extends ChessPiece { public Queen(String color, int x, int y) { super(color, x, y); @@ -10,16 +14,81 @@ public Queen(String color, int x, int y) { /** * Returns all possible moves for a bishop from the given position on an 8x8 chessboard. * - * @param position the position of the current piece * @return A list of int arrays, each representing a valid move [newX, newY]. */ - public ArrayList getValidMoves() { - final ArrayList validMoves = new ArrayList<>(); + @SuppressWarnings({"checkstyle:CyclomaticComplexity", "checkstyle:MagicNumber", "checkstyle:SuppressWarnings"}) + public T getValidMoves() { + final ArrayList> validMoves = new ArrayList<>(); + // Initialize four ArrayLists for each diagonal direction + final ArrayList upLeft = new ArrayList<>(); + final ArrayList upRight = new ArrayList<>(); + final ArrayList downLeft = new ArrayList<>(); + final ArrayList downRight = new ArrayList<>(); + final int x = this.getPosition()[0]; final int y = this.getPosition()[1]; - //yet to be implemented + // Up-Left Diagonal + int i = 1; + while (x - i >= 0 && y - i >= 0) { + upLeft.add(0, new int[]{x - i, y - i}); + i++; + } + + // Up-Right Diagonal + i = 1; + while (x + i < 8 && y - i >= 0) { + upRight.add(0, new int[]{x + i, y - i}); + i++; + } + + // Down-Left Diagonal + i = 1; + while (x - i >= 0 && y + i < 8) { + downLeft.add(0, new int[]{x - i, y + i}); + i++; + } + + // Down-Right Diagonal + i = 1; + while (x + i < 8 && y + i < 8) { + downRight.add(0, new int[]{x + i, y + i}); + i++; + } + Collections.reverse(upLeft); + Collections.reverse(upRight); + Collections.reverse(downLeft); + Collections.reverse(downRight); + validMoves.add(upLeft); + validMoves.add(upRight); + validMoves.add(downLeft); + validMoves.add(downRight); + + final ArrayList upMoves = new ArrayList<>(); + final ArrayList downMoves = new ArrayList<>(); + final ArrayList leftMoves = new ArrayList<>(); + final ArrayList rightMoves = new ArrayList<>(); + + for (int j = y - 1; j >= 0; j--) { + upMoves.add(new int[] {x, j}); + } + + for (int j = y + 1; j < 8; j++) { + downMoves.add(new int[] {x, j}); + } + + for (int j = x - 1; j >= 0; j--) { + leftMoves.add(new int[] {j, y}); + } + + for (int j = x + 1; j < 8; j++) { + rightMoves.add(new int[] {j, y}); + } - return validMoves; + validMoves.add(upMoves); + validMoves.add(downMoves); + validMoves.add(leftMoves); + validMoves.add(rightMoves); + return (T) validMoves; } -} \ No newline at end of file +} diff --git a/src/main/java/entity/Rook.java b/src/main/java/entity/Rook.java index a51e6dc04..4286543fc 100644 --- a/src/main/java/entity/Rook.java +++ b/src/main/java/entity/Rook.java @@ -13,25 +13,40 @@ public Rook(String color, int x, int y) { * Return valid moves. */ - public ArrayList getValidMoves() { + @Override + public T getValidMoves() { + final ArrayList> validMoves = new ArrayList<>(); + + ArrayList upMoves = new ArrayList<>(); + ArrayList downMoves = new ArrayList<>(); + ArrayList leftMoves = new ArrayList<>(); + ArrayList rightMoves = new ArrayList<>(); - ArrayList validMoves = new ArrayList<>(); final int x = this.getPosition()[0]; final int y = this.getPosition()[1]; for (int i = y - 1; i >= 0; i--) { - validMoves.add(new int[] {x, i}); // Move upwards in the column + upMoves.add(new int[] {x, i}); } + for (int i = y + 1; i < 8; i++) { - validMoves.add(new int[] {x, i}); // Move downwards in the column + downMoves.add(new int[] {x, i}); } for (int i = x - 1; i >= 0; i--) { - validMoves.add(new int[] {i, y}); // Move left in the row + leftMoves.add(new int[] {i, y}); } + for (int i = x + 1; i < 8; i++) { - validMoves.add(new int[] {i, y}); // Move right in the row + rightMoves.add(new int[] {i, y}); } - return validMoves; + + validMoves.add(upMoves); + validMoves.add(downMoves); + validMoves.add(leftMoves); + validMoves.add(rightMoves); + + return (T) validMoves; } + } diff --git a/src/main/java/interface_adapter/move/MoveController.java b/src/main/java/interface_adapter/move/MoveController.java index a9f7ca5cf..d89e1fc9c 100644 --- a/src/main/java/interface_adapter/move/MoveController.java +++ b/src/main/java/interface_adapter/move/MoveController.java @@ -1,6 +1,5 @@ package interface_adapter.move; - import use_case.move.MoveInputBoundary; import use_case.move.MoveInputdata; /** diff --git a/src/main/java/interface_adapter/move/MovePresenter.java b/src/main/java/interface_adapter/move/MovePresenter.java index 90bce3733..7fc0b5260 100644 --- a/src/main/java/interface_adapter/move/MovePresenter.java +++ b/src/main/java/interface_adapter/move/MovePresenter.java @@ -61,7 +61,7 @@ else if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.Queen) { if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { pieces[7-i][j]= "♕"; } else { - pieces[7-i][j]= "♕"; + pieces[7-i][j]= "♛"; } } else if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.King) { diff --git a/src/main/java/use_case/move/MoveInteractor.java b/src/main/java/use_case/move/MoveInteractor.java index c682b835f..4c24b8ee1 100644 --- a/src/main/java/use_case/move/MoveInteractor.java +++ b/src/main/java/use_case/move/MoveInteractor.java @@ -2,10 +2,15 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Iterator; +import entity.Bishop; import entity.ChessPiece; import entity.Game; - +import entity.King; +import entity.Knight; +import entity.Queen; +import entity.Rook; /** * Move interactor who handles the business logic of move. @@ -25,13 +30,103 @@ public MoveInteractor(MoveDataAccessInterface moveDataAccessObject, /** * Return a list of valid moves based on the chess game. + * * @param chessPiece the piece + * @return return valid moves */ + @SuppressWarnings({"checkstyle:MagicNumber", "checkstyle:SuppressWarnings"}) private ArrayList validmoves(ChessPiece chessPiece) { - ArrayList full_list; - full_list = chessPiece.getValidMoves(); - //reduce full_list to a limited list based on the game, still to be implented - return full_list; + final ArrayList validList; + final ArrayList> listed; + if (chessPiece instanceof Knight || chessPiece instanceof King) { + validList = chessPiece.getValidMoves(); + final Iterator iterator = validList.iterator(); + + while (iterator.hasNext()) { + final int[] pos = iterator.next(); + if (game.getBoard().getPiece(pos) != null) { + if (game.getBoard().getPiece(pos).getColor().equals(chessPiece.getColor())) { + iterator.remove(); + } + } + } + } + else if (chessPiece instanceof Bishop || chessPiece instanceof Rook) { + validList = new ArrayList<>(); + listed = chessPiece.getValidMoves(); + + for (int i = 0; i <= 3; i++) { + for (int[] pos:listed.get(i)) { + if (game.getBoard().getPiece(pos) != null) { + if (game.getBoard().getPiece(pos).getColor().equals(chessPiece.getColor())) { + break; + } + else { + validList.add(pos); + break; + } + } + else { + validList.add(pos); + } + } + } + + } + else if (chessPiece instanceof Queen) { + validList = new ArrayList<>(); + listed = chessPiece.getValidMoves(); + for (int i = 0; i <= 7; i++) { + for (int[] pos:listed.get(i)) { + if (game.getBoard().getPiece(pos) != null) { + if (game.getBoard().getPiece(pos).getColor().equals(chessPiece.getColor())) { + break; + } + else { + validList.add(pos); + break; + } + } + else { + validList.add(pos); + } + } + } + + } + else { + validList = chessPiece.getValidMoves(); + + if (game.getBoard().getPiece(validList.get(2)) != null) { + validList.remove(2); + if (validList.size() == 3) { + validList.remove(2); + } + } + if (validList.get(1)[1] > 7 || validList.get(1)[1] < 0) { + validList.remove(1); + } + else if (game.getBoard().getPiece(validList.get(1)) != null) { + if (game.getBoard().getPiece(validList.get(1)).getColor().equals(chessPiece.getColor())) { + validList.remove(1); + } + } + else { + validList.remove(1); + } + if (validList.get(0)[1] > 7 || validList.get(0)[1] < 0) { + validList.remove(0); + } + else if (game.getBoard().getPiece(validList.get(0)) != null) { + if (game.getBoard().getPiece(validList.get(0)).getColor().equals(chessPiece.getColor())) { + validList.remove(0); + } + } + else { + validList.remove(0); + } + } + return validList; } @Override @@ -40,17 +135,15 @@ public void execute(MoveInputdata position) { if (game.getGameMode()) { select(pos); } - else if (game.getBoard().getPiece(pos) != null) { - if (game.getBoard().getPiece(pos).getColor().equals(game.getChesspiece_to_move().getColor())) { - select(pos); - } - else { - move(pos); - } - } else { move(pos); } + if (game.getBoard().over().equals("White")) { + // display white lost + } + else if (game.getBoard().over().equals("Black")) { + // display black lost + } } @@ -60,8 +153,9 @@ else if (game.getBoard().getPiece(pos) != null) { */ private void select(int[] position) { final ChessPiece piece = game.getBoard().getPiece(position); - if (piece == null) { - //Nothing happends since no piece selected + if (piece == null || game.getCurrentPlayer() && game.getBoard().getPiece(position).getColor().equals("White") + || !game.getCurrentPlayer() && game.getBoard().getPiece(position).getColor().equals("Black")) { + // Nothing happens since no piece selected final MoveOutputdata nulldata = new MoveOutputdata(new ArrayList<>(), game.getBoard()); moveOutPutBoundary.prepareMove(nulldata); } @@ -73,16 +167,32 @@ private void select(int[] position) { } } + @SuppressWarnings({"checkstyle:MagicNumber", "checkstyle:SuppressWarnings"}) private void move(int[] pos) { final ArrayList validmoves = validmoves(game.getChesspiece_to_move()); + if (containsArray(validmoves, pos)) { - game.getBoard().moveToLocation(pos, game.getChesspiece_to_move()); //Move the chess piece to location + // Move the chess piece to location + game.getBoard().moveToLocation(pos, game.getChesspiece_to_move()); + final MoveOutputdata movedata = new MoveOutputdata(new ArrayList<>(), game.getBoard()); + moveOutPutBoundary.prepareMove(movedata); + game.switchMode(); + game.switchTurn(); + } + else if (game.getBoard().getPiece(pos) instanceof Rook + && game.getBoard().getPiece(new int[] {pos[0], pos[1] - 1}) == null + && game.getBoard().getPiece(new int[] {pos[0], pos[1] - 2}) == null + && game.getBoard().getPiece(new int[] {pos[0], pos[1] - 3}) instanceof King) { + final ChessPiece temp = game.getBoard().getPiece(pos); + game.getBoard().moveToLocation(new int[] {pos[0], pos[1] - 1}, game.getChesspiece_to_move()); + game.getBoard().moveToLocation(new int[] {pos[0], pos[1] - 2}, temp); final MoveOutputdata movedata = new MoveOutputdata(new ArrayList<>(), game.getBoard()); moveOutPutBoundary.prepareMove(movedata); game.switchMode(); + game.switchTurn(); } else { - // Do Nothing since nothing happend + // Attempt to move to a invalid square final MoveOutputdata nulldata = new MoveOutputdata(new ArrayList<>(), game.getBoard()); moveOutPutBoundary.prepareMove(nulldata); game.switchMode(); @@ -90,6 +200,12 @@ private void move(int[] pos) { } } + /** + * Executes the usecase when a piece is selected. + * @param list The list of integer arrays to search through. + * @param target The target array to search for in the list. + * @return {@code true} if the target array is found in the list, {@code false} otherwise. + */ public static boolean containsArray(ArrayList list, int[] target) { if (list == null || target == null) { return false; @@ -102,3 +218,4 @@ public static boolean containsArray(ArrayList list, int[] target) { return false; } } + diff --git a/src/main/java/view/ChessBoardView.java b/src/main/java/view/ChessBoardView.java index 975bce79e..cc550db08 100644 --- a/src/main/java/view/ChessBoardView.java +++ b/src/main/java/view/ChessBoardView.java @@ -79,7 +79,8 @@ public void setMoveController(MoveController moveController) { @Override public void actionPerformed(ActionEvent e) { System.out.println(e.getActionCommand()); - String[] parts = e.getActionCommand().split(","); // Split the string at the comma + // Split the string at the comma + String[] parts = e.getActionCommand().split(","); // Convert the parts to integers int x = Integer.parseInt(parts[0]); int y = Integer.parseInt(parts[1]); From b7743cdf6ade9f0ded0f1ade9e6c700378404dd1 Mon Sep 17 00:00:00 2001 From: J0hnDing Date: Mon, 2 Dec 2024 23:34:02 -0500 Subject: [PATCH 089/125] small fix on turns --- src/main/java/use_case/move/MoveInteractor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/use_case/move/MoveInteractor.java b/src/main/java/use_case/move/MoveInteractor.java index 4c24b8ee1..76c8b2ca2 100644 --- a/src/main/java/use_case/move/MoveInteractor.java +++ b/src/main/java/use_case/move/MoveInteractor.java @@ -153,8 +153,8 @@ else if (game.getBoard().over().equals("Black")) { */ private void select(int[] position) { final ChessPiece piece = game.getBoard().getPiece(position); - if (piece == null || game.getCurrentPlayer() && game.getBoard().getPiece(position).getColor().equals("White") - || !game.getCurrentPlayer() && game.getBoard().getPiece(position).getColor().equals("Black")) { + if (piece == null || game.getCurrentPlayer() && game.getBoard().getPiece(position).getColor().equals("Black") + || !game.getCurrentPlayer() && game.getBoard().getPiece(position).getColor().equals("White")) { // Nothing happens since no piece selected final MoveOutputdata nulldata = new MoveOutputdata(new ArrayList<>(), game.getBoard()); moveOutPutBoundary.prepareMove(nulldata); From 7190d8db744ebbeac3ebdac6a624d9a442cbe7a7 Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Tue, 3 Dec 2024 00:03:55 -0500 Subject: [PATCH 090/125] Login and Signup Test --- src/main/java/app/MainChessAPP.java | 7 +++- src/test/java/SignupANDLogin/LoginTest.java | 38 ++++++++++++++++++++ src/test/java/SignupANDLogin/SignupTest.java | 38 ++++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 src/test/java/SignupANDLogin/LoginTest.java create mode 100644 src/test/java/SignupANDLogin/SignupTest.java diff --git a/src/main/java/app/MainChessAPP.java b/src/main/java/app/MainChessAPP.java index f338a9fd7..9f54d67ab 100644 --- a/src/main/java/app/MainChessAPP.java +++ b/src/main/java/app/MainChessAPP.java @@ -13,7 +13,12 @@ import interface_adapter.login.LoginViewModel; import interface_adapter.showProfile.ShowProfileViewModel; import interface_adapter.signup.SignupViewModel; -import view.*; +import view.ChessBoardView; +import view.LoggedInView; +import view.LoginView; +import view.ProfileView; +import view.SignupView; +import view.ViewManager; /** * Main that activates login page. diff --git a/src/test/java/SignupANDLogin/LoginTest.java b/src/test/java/SignupANDLogin/LoginTest.java new file mode 100644 index 000000000..55564831b --- /dev/null +++ b/src/test/java/SignupANDLogin/LoginTest.java @@ -0,0 +1,38 @@ +package SignupANDLogin; + +import data_access.UserDataAccessObject; +import entity.User; +import org.junit.Test; +import use_case.login.*; + +import static org.junit.Assert.*; + +public class LoginTest { + + @Test + public void successTest() { + LoginInputData inputData = new LoginInputData("uno", "uno"); + LoginUserDataAccessInterface userRepository = new UserDataAccessObject(); + + User user = new User("uno", "uno"); + userRepository.save(user); + + LoginOutputBoundary successPresenter = new LoginOutputBoundary() { + @Override + public void prepareSuccessView(LoginOutputData user) { + assertEquals("uno", user.getUsername()); + } + + @Override + public void prepareFailView(String error) { + fail("Use case failure is unexpected."); + } + + @Override + public void switchToSignUpView(){} + }; + + LoginInputBoundary interactor = new LoginInteractor(userRepository, successPresenter); + interactor.execute(inputData); + } +} \ No newline at end of file diff --git a/src/test/java/SignupANDLogin/SignupTest.java b/src/test/java/SignupANDLogin/SignupTest.java new file mode 100644 index 000000000..04c776e53 --- /dev/null +++ b/src/test/java/SignupANDLogin/SignupTest.java @@ -0,0 +1,38 @@ +package SignupANDLogin; + +import org.junit.Test; +import use_case.signup.*; +import data_access.UserDataAccessObject; + +import static org.junit.Assert.*; + +public class SignupTest { + + @Test + public void successTest() { + SignupInputData inputData = new SignupInputData("uno", "uno", "uno"); + SignupUserDataAccessInterface userRepository = new UserDataAccessObject(); + + SignupOutputBoundary successPresenter = new SignupOutputBoundary() { + @Override + public void prepareSuccessView(SignupOutputData user) { + // 2 things to check: the output data is correct, and the user has been created in the DAO. + assertEquals("uno", user.getUsername()); + assertTrue(userRepository.existsByName("uno")); + } + + @Override + public void prepareFailView(String error) { + fail("Use case failure is unexpected."); + } + + @Override + public void switchToLoginView() { + // This is expected + } + }; + + SignupInputBoundary interactor = new SignupInteractor(userRepository, successPresenter); + interactor.execute(inputData); + } +} From 4ea633cc8ed5586a1ba43914c3a8f968c9560a44 Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Tue, 3 Dec 2024 01:02:52 -0500 Subject: [PATCH 091/125] MainChessAPP to MainChessApp (Checkstyle) --- src/main/java/app/{MainChessAPP.java => MainChessApp.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/java/app/{MainChessAPP.java => MainChessApp.java} (99%) diff --git a/src/main/java/app/MainChessAPP.java b/src/main/java/app/MainChessApp.java similarity index 99% rename from src/main/java/app/MainChessAPP.java rename to src/main/java/app/MainChessApp.java index 9f54d67ab..01c407869 100644 --- a/src/main/java/app/MainChessAPP.java +++ b/src/main/java/app/MainChessApp.java @@ -23,7 +23,7 @@ /** * Main that activates login page. */ -public class MainChessAPP { +public class MainChessApp { /** * The main method for starting the program with an external database used to persist user data. From c54309615f4e5f307355a3b49e61c1f62a47942d Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Tue, 3 Dec 2024 01:11:00 -0500 Subject: [PATCH 092/125] Checkstyles --- src/main/java/app/LoginUseCaseFactory.java | 1 + .../java/app/ShowProfileUseCaseFactory.java | 3 +- .../interface_adapter/move/MovePresenter.java | 33 ++++++++----------- src/main/java/view/LoginView.java | 2 -- 4 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/main/java/app/LoginUseCaseFactory.java b/src/main/java/app/LoginUseCaseFactory.java index daa4ef2ac..d0d6fef26 100644 --- a/src/main/java/app/LoginUseCaseFactory.java +++ b/src/main/java/app/LoginUseCaseFactory.java @@ -28,6 +28,7 @@ private LoginUseCaseFactory() { * @param loginViewModel the LoginViewModel to inject into the LoginView * @param loggedInViewModel the LoggedInViewModel to inject into the LoginView * @param userDataAccessObject the LoginUserDataAccessInterface to inject into the LoginView + * @param signupViewModel the SignupViewModel to inject into the LoginView * @return the LoginView created for the provided input classes */ public static LoginView create( diff --git a/src/main/java/app/ShowProfileUseCaseFactory.java b/src/main/java/app/ShowProfileUseCaseFactory.java index 039b466ec..81cd37a17 100644 --- a/src/main/java/app/ShowProfileUseCaseFactory.java +++ b/src/main/java/app/ShowProfileUseCaseFactory.java @@ -45,7 +45,7 @@ public static LoggedInView create( ShowProfileUserDataAccessInterface userDataAccessObject) { final ShowProfileController showProfileController = - createShowProfileUseCase(viewManagerModel, loggedInViewModel, + createShowProfileUseCase(viewManagerModel, showProfileViewModel, userDataAccessObject); final LoggedInController loggedInController = createLoggedInUseCase(viewManagerModel, loggedInViewModel, @@ -56,7 +56,6 @@ public static LoggedInView create( private static ShowProfileController createShowProfileUseCase( ViewManagerModel viewManagerModel, - LoggedInViewModel loggedInViewModel, ShowProfileViewModel showProfileViewModel, ShowProfileUserDataAccessInterface userDataAccessObject) { diff --git a/src/main/java/interface_adapter/move/MovePresenter.java b/src/main/java/interface_adapter/move/MovePresenter.java index 2520b1284..7284c5ab1 100644 --- a/src/main/java/interface_adapter/move/MovePresenter.java +++ b/src/main/java/interface_adapter/move/MovePresenter.java @@ -1,14 +1,10 @@ package interface_adapter.move; -//import chariot.model.MoveInfo; -//import chariot.util.Board; import interface_adapter.ViewManagerModel; -import use_case.move.MoveInputdata; +import java.util.ArrayList; import use_case.move.MoveOutputBoundary; import use_case.move.MoveOutputdata; -import java.util.ArrayList; - /** * The presenter for Move use case. */ @@ -21,54 +17,53 @@ public MovePresenter(MoveViewModel moveViewModel, ViewManagerModel viewManagerMo this.viewManagerModel = viewManagerModel; } - public void prepareMove(MoveOutputdata input) { String[][] pieces = new String[8][8]; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { if (input.getBoard().isEmpty(new int[] {i, j})) { - pieces[7-i][j] = null; + pieces[7 - i][j] = null; } else { if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.Bishop) { if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { - pieces[7-i][j] = "♗"; + pieces[7 - i][j] = "♗"; } else { - pieces[7-i][j] = "♝"; + pieces[7 - i][j] = "♝"; } } else if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.Rook) { if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { - pieces[7-i][j] = "♖"; + pieces[7 - i][j] = "♖"; } else { - pieces[7-i][j] = "♜"; + pieces[7 - i][j] = "♜"; } } else if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.Knight) { if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { - pieces[7-i][j] = "♘"; + pieces[7 - i][j] = "♘"; } else { - pieces[7-i][j] = "♞"; + pieces[7 - i][j] = "♞"; } } else if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.Pawn) { if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { - pieces[7-i][j] = "♙"; + pieces[7 - i][j] = "♙"; } else { - pieces[7-i][j] = "♟"; + pieces[7 - i][j] = "♟"; } } else if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.Queen) { if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { - pieces[7-i][j]= "♕"; + pieces[7 - i][j] = "♕"; } else { - pieces[7-i][j]= "♕"; + pieces[7 - i][j] = "♕"; } } else if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.King) { if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { - pieces[7-i][j] = "♔"; + pieces[7 - i][j] = "♔"; } else { - pieces[7-i][j] = "♚"; + pieces[7 - i][j] = "♚"; } } } diff --git a/src/main/java/view/LoginView.java b/src/main/java/view/LoginView.java index 473fb9084..8b0f0bf6f 100644 --- a/src/main/java/view/LoginView.java +++ b/src/main/java/view/LoginView.java @@ -72,8 +72,6 @@ public void actionPerformed(ActionEvent evt) { } ); - //cancel.addActionListener(this); - cancel.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { From 0fa6d3c90c3e53f2348e067d018dafa80cb2f4b0 Mon Sep 17 00:00:00 2001 From: 207moment Date: Tue, 3 Dec 2024 01:11:16 -0500 Subject: [PATCH 093/125] Readme update for daily puzzle --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 350038f3c..0d81beae7 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ To Login: Click ```Login``` to navigate to a login page, enter username and pass ### Show Profile -User can view there profile (Contain User name and rank point currently) after login by click ```Show Profile``` after login. +User can view their profile (Contain User name and rank point currently) after login by click ```Show Profile``` after login. Note: New user's rank point is set to ```0``` @@ -70,7 +70,8 @@ Note: New user's rank point is set to ```0``` ### Generate daily puzzle -// TODO +This requests the algebraic chess notation for the current daily puzzle in the Lichess API +and stores the set of solutions and the series of moves to create the puzzle board. ### Step by step move From 7d53a34351d1002c87b8fb6db5f3ecf98adf480c Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Tue, 3 Dec 2024 03:58:29 -0500 Subject: [PATCH 094/125] Created UserAppBuilder and moved codes from MainChessApp to UserAppBuilder to follow the Clean Architecture --- src/main/java/app/MainChessApp.java | 68 ++-------------- src/main/java/app/UserAppBuilder.java | 113 ++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 61 deletions(-) create mode 100644 src/main/java/app/UserAppBuilder.java diff --git a/src/main/java/app/MainChessApp.java b/src/main/java/app/MainChessApp.java index 01c407869..bda32d33a 100644 --- a/src/main/java/app/MainChessApp.java +++ b/src/main/java/app/MainChessApp.java @@ -1,24 +1,6 @@ package app; -import java.awt.CardLayout; - import javax.swing.JFrame; -import javax.swing.JPanel; -import javax.swing.WindowConstants; - -import data_access.ChessDataAccessObject; -import data_access.UserDataAccessObject; -import interface_adapter.ViewManagerModel; -import interface_adapter.logged_in.LoggedInViewModel; -import interface_adapter.login.LoginViewModel; -import interface_adapter.showProfile.ShowProfileViewModel; -import interface_adapter.signup.SignupViewModel; -import view.ChessBoardView; -import view.LoggedInView; -import view.LoginView; -import view.ProfileView; -import view.SignupView; -import view.ViewManager; /** * Main that activates login page. @@ -31,48 +13,12 @@ public class MainChessApp { */ public static void main(String[] args) { - final JFrame frame = new JFrame("Chess Game Login"); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - - final CardLayout cardLayout = new CardLayout(); - final JPanel views = new JPanel(cardLayout); - frame.add(views); - - final ViewManagerModel viewManagerModel = new ViewManagerModel(); - new ViewManager(views, cardLayout, viewManagerModel); - - final LoginViewModel loginViewModel = new LoginViewModel(); - final LoggedInViewModel loggedInViewModel = new LoggedInViewModel(); - final SignupViewModel signupViewModel = new SignupViewModel(); - final ShowProfileViewModel showProfileViewModel = new ShowProfileViewModel(); - - final UserDataAccessObject userDataAccessObject = new UserDataAccessObject(); - - final SignupView signupView = SignupUseCaseFactory.create(viewManagerModel, loginViewModel, - signupViewModel, userDataAccessObject); - final LoginView loginView = LoginUseCaseFactory.create(viewManagerModel, loginViewModel, - loggedInViewModel, userDataAccessObject, signupViewModel); - final LoggedInView loggedInView = ShowProfileUseCaseFactory.create(viewManagerModel, loggedInViewModel, - signupViewModel, showProfileViewModel, userDataAccessObject); - final ProfileView profileView = new ProfileView(viewManagerModel, showProfileViewModel); - - views.add(signupView, signupView.getViewName()); - views.add(loginView, loginView.getViewName()); - views.add(loggedInView, loggedInView.getViewName()); - views.add(profileView, profileView.getViewName()); - - final ChessAppBuilder chessAppBuilder = new ChessAppBuilder(); - chessAppBuilder.addChessDAO(new ChessDataAccessObject()) - .addMoveView() - .addMoveUseCase(); - - final ChessBoardView chessBoardView = chessAppBuilder.buildChessBoardView(); - views.add(chessBoardView, "chessBoardView"); - - viewManagerModel.setState(signupView.getViewName()); - viewManagerModel.firePropertyChanged(); - - frame.pack(); - frame.setVisible(true); + final UserAppBuilder userAppBuilder = new UserAppBuilder(); + final JFrame application = userAppBuilder + .addViewModels() + .addViews() + .initializeState() + .addChessGame() + .build(); } } diff --git a/src/main/java/app/UserAppBuilder.java b/src/main/java/app/UserAppBuilder.java new file mode 100644 index 000000000..d8082414a --- /dev/null +++ b/src/main/java/app/UserAppBuilder.java @@ -0,0 +1,113 @@ +package app; + +import java.awt.CardLayout; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.WindowConstants; + +import data_access.ChessDataAccessObject; +import data_access.UserDataAccessObject; +import interface_adapter.ViewManagerModel; +import interface_adapter.logged_in.LoggedInViewModel; +import interface_adapter.login.LoginViewModel; +import interface_adapter.showProfile.ShowProfileViewModel; +import interface_adapter.signup.SignupViewModel; +import view.ChessBoardView; +import view.LoggedInView; +import view.LoginView; +import view.ProfileView; +import view.SignupView; +import view.ViewManager; + +public class UserAppBuilder { + private CardLayout cardLayout; + private JPanel views; + private ViewManagerModel viewManagerModel; + private ChessBoardView chessBoardView; + private UserDataAccessObject userDataAccessObject; + + private LoginViewModel loginViewModel; + private LoggedInViewModel loggedInViewModel; + private SignupViewModel signupViewModel; + private ShowProfileViewModel showProfileViewModel; + + public UserAppBuilder() { + this.cardLayout = new CardLayout(); + this.views = new JPanel(cardLayout); + this.viewManagerModel = new ViewManagerModel(); + this.userDataAccessObject = new UserDataAccessObject(); + new ViewManager(views, cardLayout, viewManagerModel); + } + + /** + * Set the addViewModels to be used in this application. + * @return this builder + */ + public UserAppBuilder addViewModels() { + this.loginViewModel = new LoginViewModel(); + this.loggedInViewModel = new LoggedInViewModel(); + this.signupViewModel = new SignupViewModel(); + this.showProfileViewModel = new ShowProfileViewModel(); + return this; + } + + /** + * Set the addViews to be used in this application. + * @return this builder + */ + public UserAppBuilder addViews() { + final SignupView signupView = SignupUseCaseFactory.create(viewManagerModel, loginViewModel, signupViewModel, + userDataAccessObject); + final LoginView loginView = LoginUseCaseFactory.create(viewManagerModel, loginViewModel, loggedInViewModel, + userDataAccessObject, signupViewModel); + final LoggedInView loggedInView = ShowProfileUseCaseFactory.create(viewManagerModel, loggedInViewModel, + signupViewModel, showProfileViewModel, userDataAccessObject); + final ProfileView profileView = new ProfileView(viewManagerModel, showProfileViewModel); + + views.add(signupView, signupView.getViewName()); + views.add(loginView, loginView.getViewName()); + views.add(loggedInView, loggedInView.getViewName()); + views.add(profileView, profileView.getViewName()); + + return this; + } + + /** + * Set the addChessGame to be used in this application. + * @return this builder + */ + public UserAppBuilder addChessGame() { + final ChessAppBuilder chessAppBuilder = new ChessAppBuilder(); + chessAppBuilder.addChessDAO(new ChessDataAccessObject()) + .addMoveView() + .addMoveUseCase(); + + this.chessBoardView = chessAppBuilder.buildChessBoardView(); + this.views.add(chessBoardView, "chessBoardView"); + return this; + } + + /** + * Set the initializeState to be used in this application. + * @return this builder + */ + public UserAppBuilder initializeState() { + this.viewManagerModel.setState("signUpView"); + this.viewManagerModel.firePropertyChanged(); + return this; + } + + /** + * Set the build to be used in this application. + * @return this builder + */ + public JFrame build() { + final JFrame frame = new JFrame("Chess Game Login"); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.add(this.views); + frame.pack(); + frame.setVisible(true); + return frame; + } +} From 87ab11a4ec1543702d4cd3b43d61470a34db9a23 Mon Sep 17 00:00:00 2001 From: Chihana Kashiwabara Date: Tue, 3 Dec 2024 04:01:48 -0500 Subject: [PATCH 095/125] CheckStyle --- src/main/java/app/MainChessApp.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/app/MainChessApp.java b/src/main/java/app/MainChessApp.java index bda32d33a..12e1010be 100644 --- a/src/main/java/app/MainChessApp.java +++ b/src/main/java/app/MainChessApp.java @@ -1,7 +1,5 @@ package app; -import javax.swing.JFrame; - /** * Main that activates login page. */ @@ -14,8 +12,7 @@ public class MainChessApp { public static void main(String[] args) { final UserAppBuilder userAppBuilder = new UserAppBuilder(); - final JFrame application = userAppBuilder - .addViewModels() + userAppBuilder.addViewModels() .addViews() .initializeState() .addChessGame() From 6e29a8c7af40c6c09388588eb693bfb59c4cce08 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Sat, 30 Nov 2024 11:25:20 -0500 Subject: [PATCH 096/125] Minor adjustment to Yann's user story. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0d81beae7..d76c1e30f 100644 --- a/README.md +++ b/README.md @@ -97,5 +97,5 @@ Group User Story. Tom generate a chess puzzle, solve it step by step, and eventu 1. John wants to play a chess puzzle. He opens the chess puzzle player and clicks generate puzzle of the day. The chess puzzle of the day loads on screen. [Michelle’s Story] 2. Tom and Tim argued about who is a better chess player, so they decided to compare their Rank point of Ranking system. [Jiaqi Ma’s Story] 3. As Mary hears about this chess puzzle, she wants to create an account and log in to start a puzzle. [Chihana’s Story] -4. Andy is learning chess, and his teacher use this program to check Andy's learning progress, by looking at past statistics of chess puzzles. The teacher can search up Andy's user account using the username. [Yann Chi's Story] +4. Andy is learning chess, and he can use this program to check his learning progress, by looking at past statistics of chess puzzles. He can search up his user account using the username. [Yann Chi's Story] 5. Felix wants to see the possible moves he can make with one piece, so he click on that piece and the possible cells will be indicated. [John’s Story] From d16d21bdac1fee7d04f5c197e4500037f7d8c9a2 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Sat, 30 Nov 2024 15:04:20 -0500 Subject: [PATCH 097/125] Added Query use case and added button of show rank history in view. --- .../query/QueryController.java | 4 +++ .../query/QueryPresenter.java | 4 +++ .../query/QueryProfileViewModel.java | 4 +++ .../interface_adapter/query/QueryState.java | 4 +++ .../query/QueryDataAccessInterface.java | 4 +++ .../use_case/query/QueryInputBoundary.java | 18 +++++++++++++ .../java/use_case/query/QueryInputData.java | 15 +++++++++++ .../java/use_case/query/QueryInteractor.java | 4 +++ .../use_case/query/QueryOutputBoundary.java | 4 +++ src/main/java/view/LoggedInView.java | 25 +++++++++++++++++++ 10 files changed, 86 insertions(+) create mode 100644 src/main/java/interface_adapter/query/QueryController.java create mode 100644 src/main/java/interface_adapter/query/QueryPresenter.java create mode 100644 src/main/java/interface_adapter/query/QueryProfileViewModel.java create mode 100644 src/main/java/interface_adapter/query/QueryState.java create mode 100644 src/main/java/use_case/query/QueryDataAccessInterface.java create mode 100644 src/main/java/use_case/query/QueryInputBoundary.java create mode 100644 src/main/java/use_case/query/QueryInputData.java create mode 100644 src/main/java/use_case/query/QueryInteractor.java create mode 100644 src/main/java/use_case/query/QueryOutputBoundary.java diff --git a/src/main/java/interface_adapter/query/QueryController.java b/src/main/java/interface_adapter/query/QueryController.java new file mode 100644 index 000000000..5fa449029 --- /dev/null +++ b/src/main/java/interface_adapter/query/QueryController.java @@ -0,0 +1,4 @@ +package interface_adapter.query; + +public class QueryController { +} diff --git a/src/main/java/interface_adapter/query/QueryPresenter.java b/src/main/java/interface_adapter/query/QueryPresenter.java new file mode 100644 index 000000000..14b19dada --- /dev/null +++ b/src/main/java/interface_adapter/query/QueryPresenter.java @@ -0,0 +1,4 @@ +package interface_adapter.query; + +public class QueryPresenter { +} diff --git a/src/main/java/interface_adapter/query/QueryProfileViewModel.java b/src/main/java/interface_adapter/query/QueryProfileViewModel.java new file mode 100644 index 000000000..0673fc325 --- /dev/null +++ b/src/main/java/interface_adapter/query/QueryProfileViewModel.java @@ -0,0 +1,4 @@ +package interface_adapter.query; + +public class QueryProfileViewModel { +} diff --git a/src/main/java/interface_adapter/query/QueryState.java b/src/main/java/interface_adapter/query/QueryState.java new file mode 100644 index 000000000..bd9021aa8 --- /dev/null +++ b/src/main/java/interface_adapter/query/QueryState.java @@ -0,0 +1,4 @@ +package interface_adapter.query; + +public class QueryState { +} diff --git a/src/main/java/use_case/query/QueryDataAccessInterface.java b/src/main/java/use_case/query/QueryDataAccessInterface.java new file mode 100644 index 000000000..dc6ec1f12 --- /dev/null +++ b/src/main/java/use_case/query/QueryDataAccessInterface.java @@ -0,0 +1,4 @@ +package use_case.query; + +public interface QueryDataAccessInterface { +} diff --git a/src/main/java/use_case/query/QueryInputBoundary.java b/src/main/java/use_case/query/QueryInputBoundary.java new file mode 100644 index 000000000..743cc81ea --- /dev/null +++ b/src/main/java/use_case/query/QueryInputBoundary.java @@ -0,0 +1,18 @@ +package use_case.query; + +/** + * Input Boundary for actions which are related to searching user. + */ +public interface QueryInputBoundary { + + /** + * Executes the search User use case. + * @param username the input data + */ + void execute(String username); + + /** + * Executes the switch to login view use case. + */ + void switchToLoginView(); +} \ No newline at end of file diff --git a/src/main/java/use_case/query/QueryInputData.java b/src/main/java/use_case/query/QueryInputData.java new file mode 100644 index 000000000..69b1f8694 --- /dev/null +++ b/src/main/java/use_case/query/QueryInputData.java @@ -0,0 +1,15 @@ +package use_case.query; + +/** + * The Input Data for the SearchUser use case. + */ + +public class QueryInputData { + private final String username; + + public QueryInputData(String username) { + this.username = username; } + + public String getUsername() { + return username; } +} diff --git a/src/main/java/use_case/query/QueryInteractor.java b/src/main/java/use_case/query/QueryInteractor.java new file mode 100644 index 000000000..dd3bea5eb --- /dev/null +++ b/src/main/java/use_case/query/QueryInteractor.java @@ -0,0 +1,4 @@ +package use_case.query; + +public class QueryInteractor { +} diff --git a/src/main/java/use_case/query/QueryOutputBoundary.java b/src/main/java/use_case/query/QueryOutputBoundary.java new file mode 100644 index 000000000..aad4accd5 --- /dev/null +++ b/src/main/java/use_case/query/QueryOutputBoundary.java @@ -0,0 +1,4 @@ +package use_case.query; + +public interface QueryOutputBoundary { +} diff --git a/src/main/java/view/LoggedInView.java b/src/main/java/view/LoggedInView.java index f0af5108a..01659fbca 100644 --- a/src/main/java/view/LoggedInView.java +++ b/src/main/java/view/LoggedInView.java @@ -6,14 +6,18 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; +import javax.swing.JTextField; import interface_adapter.ViewManagerModel; import interface_adapter.logged_in.LoggedInController; import interface_adapter.logged_in.LoggedInState; import interface_adapter.logged_in.LoggedInViewModel; +import interface_adapter.login.LoginState; +import interface_adapter.query.QueryController; import interface_adapter.showProfile.ShowProfileController; /** @@ -30,8 +34,10 @@ public class LoggedInView extends JPanel implements ActionListener, PropertyChan private final JButton logOut; + private final JTextField passwordInputField = new JTextField(15); private final JButton startChess; private final JButton showProfile; + private final JButton showRankHistory; private final ShowProfileController showProfileController; public LoggedInView(ViewManagerModel viewManagerModel, LoggedInController loggedInController, @@ -52,11 +58,15 @@ public LoggedInView(ViewManagerModel viewManagerModel, LoggedInController logged logOut = new JButton("Log Out"); buttons.add(logOut); + showRankHistory = new JButton("Show Rank History"); + showProfile = new JButton("Show Profile"); buttons.add(showProfile); startChess = new JButton("Start Chess Game"); buttons.add(startChess); + buttons.add(showProfile); + buttons.add(showRankHistory); logOut.addActionListener( new ActionListener() { @@ -91,10 +101,25 @@ public void actionPerformed(ActionEvent evt) { } ); + showRankHistory.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(showRankHistory)) { + final LoggedInState currentState = loggedInViewModel.getState(); + + QueryController.execute( + currentState.getUsername() + ); + } + } + } + ); + this.add(title); this.add(usernameInfo); this.add(username); + this.add(passwordInfo); this.add(passwordErrorField); this.add(buttons); } From 54c220e642324ff1768413375720e662ec03c9b1 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Sat, 30 Nov 2024 23:45:55 -0500 Subject: [PATCH 098/125] Update Query view in interface adapter and create Query DAO file. --- .../data_access/QueryDataAccessObject.java | 67 +++++++++++++++++++ .../query/QueryController.java | 23 +++++++ .../query/QueryPresenter.java | 33 ++++++++- .../query/QueryProfileViewModel.java | 4 -- .../interface_adapter/query/QueryState.java | 24 +++++++ .../query/QueryViewModel.java | 24 +++++++ 6 files changed, 170 insertions(+), 5 deletions(-) create mode 100644 src/main/java/data_access/QueryDataAccessObject.java delete mode 100644 src/main/java/interface_adapter/query/QueryProfileViewModel.java create mode 100644 src/main/java/interface_adapter/query/QueryViewModel.java diff --git a/src/main/java/data_access/QueryDataAccessObject.java b/src/main/java/data_access/QueryDataAccessObject.java new file mode 100644 index 000000000..8790feeab --- /dev/null +++ b/src/main/java/data_access/QueryDataAccessObject.java @@ -0,0 +1,67 @@ +package data_access; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import use_case.daily_puzzle.PuzzleAccessException; +import use_case.query.QueryDataAccessInterface; + +import java.io.IOException; +import java.util.ArrayList; + +public class QueryDataAccessObject implements QueryDataAccessInterface { + private static final int SUCCESS_CODE = 200; + private static final String LICHESS_PUZZLE_URL = "https://lichess.org/api/puzzle/"; + private static final String DAILY_PUZZLE_URL = "daily"; + private static String PUZZLE_FROM_ID_URL; + + public ArrayList getDaily() throws PuzzleAccessException { + final OkHttpClient client = new OkHttpClient().newBuilder().build(); + final Request request = new Request.Builder().url(LICHESS_PUZZLE_URL + DAILY_PUZZLE_URL).build(); + ArrayList output = null; + + try { + final Response response = client.newCall(request).execute(); + + final JSONObject responseBody = new JSONObject(response.body().string()); + + JSONObject puzzle = responseBody.getJSONObject("puzzle"); + JSONArray solution = puzzle.getJSONArray("solution"); + output.add(puzzle.getString("id")); + for (int i = 0; i < solution.length(); i++) { + output.add(solution.getString(i)); + } + } + catch (final IOException | JSONException e) { + throw new PuzzleAccessException(e.getMessage()); + } + return output; +} + +@Override +public ArrayList fetchPuzzle(String id) throws PuzzleAccessException { + final OkHttpClient client = new OkHttpClient().newBuilder().build(); + final Request request = new Request.Builder().url(LICHESS_PUZZLE_URL + PUZZLE_FROM_ID_URL).build(); + ArrayList output = null; + + try { + final Response response = client.newCall(request).execute(); + + final JSONObject responseBody = new JSONObject(response.body().string()); + + JSONArray solution = responseBody.getJSONArray("solution"); + output.add(responseBody.getJSONObject("game").getString("pgn")); + for (int i = 0; i < solution.length(); i++) { + output.add(solution.getString(i)); + } + } + catch (final IOException | JSONException e) { + throw new PuzzleAccessException(e.getMessage()); + } + return output; +} +} +} diff --git a/src/main/java/interface_adapter/query/QueryController.java b/src/main/java/interface_adapter/query/QueryController.java index 5fa449029..333a60596 100644 --- a/src/main/java/interface_adapter/query/QueryController.java +++ b/src/main/java/interface_adapter/query/QueryController.java @@ -1,4 +1,27 @@ package interface_adapter.query; +import use_case.query.QueryInputBoundary; +import use_case.query.QueryInputData; + +/** + * The controller for the ShowProfile use case. + */ public class QueryController { + + private final QueryInputBoundary QueryInputInteractor; + + public QueryController(QueryInputBoundary QueryInteractor) { + this.QueryInputInteractor = QueryInteractor; + } + + /** + * Execute the showProfile use case. + * @param username the username of the user logging in + */ + public void execute(String username) { + final QueryInputData queryInputData = new QueryInputData(username); + + QueryInputInteractor.execute(queryInputData); + } } + diff --git a/src/main/java/interface_adapter/query/QueryPresenter.java b/src/main/java/interface_adapter/query/QueryPresenter.java index 14b19dada..b9c4c8dc7 100644 --- a/src/main/java/interface_adapter/query/QueryPresenter.java +++ b/src/main/java/interface_adapter/query/QueryPresenter.java @@ -1,4 +1,35 @@ package interface_adapter.query; -public class QueryPresenter { +import interface_adapter.ViewManagerModel; +import use_case.query.QueryOutputBoundary; +import use_case.query.QueryOutputData; +import view.ViewManager; + +public class QueryPresenter implements QueryOutputBoundary { + + private final QueryViewModel queryViewModel; + private final ViewManagerModel viewManagerModel; + + public QueryPresenter(QueryViewModel queryViewModel, ViewManagerModel viewManagerModel) { + this.queryViewModel = queryViewModel; + this.viewManagerModel = viewManagerModel; + } + + @Override + public void prepareSuccessView(QueryOutputData outputData) { + // On success, switch to the Profile view. + + final QueryState queryState = queryViewModel.getState(); + queryState.setUsername(outputData.getUsername()); + this.queryViewModel.setState(queryState); + this.queryViewModel.firePropertyChanged(); + + this.viewManagerModel.setState(queryViewModel.getViewName()); + this.viewManagerModel.firePropertyChanged(); + } + + @Override + public void prepareFailView(String errorMessage) { + + } } diff --git a/src/main/java/interface_adapter/query/QueryProfileViewModel.java b/src/main/java/interface_adapter/query/QueryProfileViewModel.java deleted file mode 100644 index 0673fc325..000000000 --- a/src/main/java/interface_adapter/query/QueryProfileViewModel.java +++ /dev/null @@ -1,4 +0,0 @@ -package interface_adapter.query; - -public class QueryProfileViewModel { -} diff --git a/src/main/java/interface_adapter/query/QueryState.java b/src/main/java/interface_adapter/query/QueryState.java index bd9021aa8..5bb4d40e6 100644 --- a/src/main/java/interface_adapter/query/QueryState.java +++ b/src/main/java/interface_adapter/query/QueryState.java @@ -1,4 +1,28 @@ package interface_adapter.query; +import java.util.ArrayList; +import java.util.Dictionary; +import java.util.List; + +/** + * The State information representing the logged-in user. + */ public class QueryState { + private String username = ""; + + public QueryState() { + + } + + public void setUsername(String username) { + this.username = username; + } + + public String getUsername() { + return username; + } + + public ArrayList getRankHistory() { + return rankHistory; + } } diff --git a/src/main/java/interface_adapter/query/QueryViewModel.java b/src/main/java/interface_adapter/query/QueryViewModel.java new file mode 100644 index 000000000..a0695bef6 --- /dev/null +++ b/src/main/java/interface_adapter/query/QueryViewModel.java @@ -0,0 +1,24 @@ +package interface_adapter.query; + +import interface_adapter.ViewModel; + +import java.util.ArrayList; + +/** + * The View Model for the query view. + */ +public class QueryViewModel extends ViewModel { + + public QueryViewModel() { + super("Query"); + setState(new QueryState()); + } + + public String getUsername() { + return getState().getUsername(); + } + + public ArrayList getRankHistory() { + return getState().getRankHistory(); + } +} From bc626a05bbb4a065e84e1d50cf153fa630d938f4 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Sun, 1 Dec 2024 00:27:21 -0500 Subject: [PATCH 099/125] Added use case output data. --- .../java/use_case/query/QueryOutputData.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/main/java/use_case/query/QueryOutputData.java diff --git a/src/main/java/use_case/query/QueryOutputData.java b/src/main/java/use_case/query/QueryOutputData.java new file mode 100644 index 000000000..1f2efae76 --- /dev/null +++ b/src/main/java/use_case/query/QueryOutputData.java @@ -0,0 +1,28 @@ +package use_case.query; + +import java.util.ArrayList; + +/** + * Output Data for the ShowProfile Use case. + */ +public class QueryOutputData { + + private final String username; + private final ArrayList RankHistory; + private final boolean useCaseSucceeded; + + public QueryOutputData(String username, ArrayList RankHistory, boolean useCaseSucceeded) { + this.username = username; + this.RankHistory = RankHistory; + this.useCaseSucceeded = useCaseSucceeded; + } + + public int getRankHistory() { + return RankHistory; + } + + public String getUsername() { + return username; + } + +} From 7089c43839d4f8612d231b1fb674644aaefa17b3 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Sun, 1 Dec 2024 00:28:38 -0500 Subject: [PATCH 100/125] Added use case output data. --- src/main/java/use_case/query/QueryOutputData.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/use_case/query/QueryOutputData.java b/src/main/java/use_case/query/QueryOutputData.java index 1f2efae76..a5d39eaac 100644 --- a/src/main/java/use_case/query/QueryOutputData.java +++ b/src/main/java/use_case/query/QueryOutputData.java @@ -8,17 +8,17 @@ public class QueryOutputData { private final String username; - private final ArrayList RankHistory; + private final ArrayList rankHistory; private final boolean useCaseSucceeded; - public QueryOutputData(String username, ArrayList RankHistory, boolean useCaseSucceeded) { + public QueryOutputData(String username, ArrayList rankHistory, boolean useCaseSucceeded) { this.username = username; - this.RankHistory = RankHistory; + this.rankHistory = rankHistory; this.useCaseSucceeded = useCaseSucceeded; } - public int getRankHistory() { - return RankHistory; + public ArrayList getRankHistory() { + return rankHistory; } public String getUsername() { From fea62de3d1dd3c488e259a765111421781c08135 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Mon, 2 Dec 2024 08:11:35 -0500 Subject: [PATCH 101/125] Update pom file and added RankHistory Entity. --- pom.xml | 5 + .../data_access/QueryDataAccessObject.java | 99 +++++++++---------- src/main/java/entity/RankHistory.java | 64 ++++++++++++ .../query/QueryController.java | 16 ++- .../query/QueryPresenter.java | 23 +++-- .../interface_adapter/query/QueryState.java | 20 ++-- .../query/QueryViewModel.java | 12 +-- 7 files changed, 149 insertions(+), 90 deletions(-) create mode 100644 src/main/java/entity/RankHistory.java diff --git a/pom.xml b/pom.xml index 428273a2a..8f715e7bf 100644 --- a/pom.xml +++ b/pom.xml @@ -32,6 +32,11 @@ chariot 0.1.10 + + com.alibaba + fastjson + 1.2.79 + diff --git a/src/main/java/data_access/QueryDataAccessObject.java b/src/main/java/data_access/QueryDataAccessObject.java index 8790feeab..4fc45c3bf 100644 --- a/src/main/java/data_access/QueryDataAccessObject.java +++ b/src/main/java/data_access/QueryDataAccessObject.java @@ -1,67 +1,60 @@ package data_access; +import java.io.IOException; + +import entity.RankHistory; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import use_case.daily_puzzle.PuzzleAccessException; import use_case.query.QueryDataAccessInterface; -import java.io.IOException; -import java.util.ArrayList; - +/** + * The DAO for accessing user rank history stored in the database. + */ public class QueryDataAccessObject implements QueryDataAccessInterface { - private static final int SUCCESS_CODE = 200; - private static final String LICHESS_PUZZLE_URL = "https://lichess.org/api/puzzle/"; - private static final String DAILY_PUZZLE_URL = "daily"; - private static String PUZZLE_FROM_ID_URL; + @Override + public RankHistory showRankHistory(String username) { - public ArrayList getDaily() throws PuzzleAccessException { - final OkHttpClient client = new OkHttpClient().newBuilder().build(); - final Request request = new Request.Builder().url(LICHESS_PUZZLE_URL + DAILY_PUZZLE_URL).build(); - ArrayList output = null; + final RankHistory rankHistory = new RankHistory(); - try { - final Response response = client.newCall(request).execute(); - - final JSONObject responseBody = new JSONObject(response.body().string()); - - JSONObject puzzle = responseBody.getJSONObject("puzzle"); - JSONArray solution = puzzle.getJSONArray("solution"); - output.add(puzzle.getString("id")); - for (int i = 0; i < solution.length(); i++) { - output.add(solution.getString(i)); + final String url = String.format("https://lichess.org/api/user/%s/rating-history", username); + final OkHttpClient client = new OkHttpClient().newBuilder().build(); + final Request request = new Request.Builder() + .url(url) + .build(); + + try (Response response = client.newCall(request).execute()) { + + final String responseBody = response.body().string(); + final com.alibaba.fastjson.JSONArray jsonArray = com.alibaba.fastjson.JSONArray.parseArray(responseBody); + + jsonArray.stream().forEach(str -> { + final com.alibaba.fastjson.JSONObject jsonObject = + com.alibaba.fastjson.JSONObject.parseObject(str.toString()); + + final String name = (String) jsonObject.get("name"); + if ("Puzzles".equals(name)) { + final Object points = jsonObject.get("points"); + final com.alibaba.fastjson.JSONArray pointarr = + com.alibaba.fastjson.JSONArray.parseArray(points.toString()); + + final Object[] objects = pointarr.toArray(); + + for (Object object : objects) { + final com.alibaba.fastjson.JSONArray ranks = + com.alibaba.fastjson.JSONArray.parseArray(object.toString()); + final int year = (Integer) ranks.get(0); + final int month = (Integer) ranks.get(1); + final int day = (Integer) ranks.get(2); + final int rank = (Integer) ranks.get(3); + rankHistory.addRankHistory(year, month, day, rank); + } + } + }); + return rankHistory; } - } - catch (final IOException | JSONException e) { - throw new PuzzleAccessException(e.getMessage()); - } - return output; -} - -@Override -public ArrayList fetchPuzzle(String id) throws PuzzleAccessException { - final OkHttpClient client = new OkHttpClient().newBuilder().build(); - final Request request = new Request.Builder().url(LICHESS_PUZZLE_URL + PUZZLE_FROM_ID_URL).build(); - ArrayList output = null; - - try { - final Response response = client.newCall(request).execute(); - - final JSONObject responseBody = new JSONObject(response.body().string()); - - JSONArray solution = responseBody.getJSONArray("solution"); - output.add(responseBody.getJSONObject("game").getString("pgn")); - for (int i = 0; i < solution.length(); i++) { - output.add(solution.getString(i)); + catch (IOException ex) { + throw new RuntimeException(ex); } } - catch (final IOException | JSONException e) { - throw new PuzzleAccessException(e.getMessage()); - } - return output; -} -} } diff --git a/src/main/java/entity/RankHistory.java b/src/main/java/entity/RankHistory.java new file mode 100644 index 000000000..e13cd9842 --- /dev/null +++ b/src/main/java/entity/RankHistory.java @@ -0,0 +1,64 @@ +package entity; + +import java.util.ArrayList; +import java.util.List; + +/** + * The representation of user rank history for our program. + */ + +public class RankHistory { + private final List rankHistoryList; + + public RankHistory() { + this.rankHistoryList = new ArrayList<>(); + } + + public List getRanks() { + return rankHistoryList; + } + + /** + * Print the RankHistory. + */ + public void printRankHistory() { + for (Rank rank : rankHistoryList) { + System.out.println(rank); + } + } + + /** + * Add user rank for our program. + * @param year the rank year. + * @param month the rank month. + * @param day the rank day. + * @param rank the rank . + */ + public void addRankHistory(int year, int month, int day, int rank) { + final Rank rh = new Rank(year, month, day, rank); + this.rankHistoryList.add(rh); + } + + /** + * The representation of user rank for our program. + */ + public static class Rank { + private final int year; + private final int month; + private final int day; + private final int rank; + + public Rank(int year, int month, int day, int rank) { + this.year = year; + this.month = month + 1; + this.day = day; + this.rank = rank; + } + + @Override + public String toString() { + return "Year:" + year + " Month:" + month + + " Day:" + day + " Rank:" + rank; + } + } +} diff --git a/src/main/java/interface_adapter/query/QueryController.java b/src/main/java/interface_adapter/query/QueryController.java index 333a60596..8bb2cadd6 100644 --- a/src/main/java/interface_adapter/query/QueryController.java +++ b/src/main/java/interface_adapter/query/QueryController.java @@ -1,27 +1,23 @@ package interface_adapter.query; import use_case.query.QueryInputBoundary; -import use_case.query.QueryInputData; /** - * The controller for the ShowProfile use case. + * The controller for the query use case. */ public class QueryController { - private final QueryInputBoundary QueryInputInteractor; + private final QueryInputBoundary queryInteractor; - public QueryController(QueryInputBoundary QueryInteractor) { - this.QueryInputInteractor = QueryInteractor; + public QueryController(QueryInputBoundary queryInteractor) { + this.queryInteractor = queryInteractor; } /** - * Execute the showProfile use case. + * Execute the query use case. * @param username the username of the user logging in */ public void execute(String username) { - final QueryInputData queryInputData = new QueryInputData(username); - - QueryInputInteractor.execute(queryInputData); + queryInteractor.execute(username); } } - diff --git a/src/main/java/interface_adapter/query/QueryPresenter.java b/src/main/java/interface_adapter/query/QueryPresenter.java index b9c4c8dc7..aa5b152a4 100644 --- a/src/main/java/interface_adapter/query/QueryPresenter.java +++ b/src/main/java/interface_adapter/query/QueryPresenter.java @@ -1,10 +1,12 @@ package interface_adapter.query; +import entity.RankHistory; import interface_adapter.ViewManagerModel; import use_case.query.QueryOutputBoundary; -import use_case.query.QueryOutputData; -import view.ViewManager; +/** + * The presenter for query viewing. + */ public class QueryPresenter implements QueryOutputBoundary { private final QueryViewModel queryViewModel; @@ -15,12 +17,16 @@ public QueryPresenter(QueryViewModel queryViewModel, ViewManagerModel viewManage this.viewManagerModel = viewManagerModel; } + /** + * Prepares the success view for the query related Use Cases. + * + * @param rankHistoryList the user rank history data. + */ @Override - public void prepareSuccessView(QueryOutputData outputData) { - // On success, switch to the Profile view. - + public void prepareSuccessView(RankHistory rankHistoryList) { + // On success, switch to the Query view. final QueryState queryState = queryViewModel.getState(); - queryState.setUsername(outputData.getUsername()); + queryState.setRankHistoryList(rankHistoryList); this.queryViewModel.setState(queryState); this.queryViewModel.firePropertyChanged(); @@ -28,6 +34,11 @@ public void prepareSuccessView(QueryOutputData outputData) { this.viewManagerModel.firePropertyChanged(); } + /** + * Prepares the failure view for the query related Use Cases. + * + * @param errorMessage the explanation of the failure + */ @Override public void prepareFailView(String errorMessage) { diff --git a/src/main/java/interface_adapter/query/QueryState.java b/src/main/java/interface_adapter/query/QueryState.java index 5bb4d40e6..66ce0bef6 100644 --- a/src/main/java/interface_adapter/query/QueryState.java +++ b/src/main/java/interface_adapter/query/QueryState.java @@ -1,28 +1,22 @@ package interface_adapter.query; -import java.util.ArrayList; -import java.util.Dictionary; -import java.util.List; +import entity.RankHistory; /** - * The State information representing the logged-in user. + * The State information representing the query user. */ public class QueryState { - private String username = ""; + private RankHistory rankHistoryList; public QueryState() { } - public void setUsername(String username) { - this.username = username; + public void setRankHistoryList(RankHistory rankHistoryList) { + this.rankHistoryList = rankHistoryList; } - public String getUsername() { - return username; - } - - public ArrayList getRankHistory() { - return rankHistory; + public RankHistory getRankHistoryList() { + return rankHistoryList; } } diff --git a/src/main/java/interface_adapter/query/QueryViewModel.java b/src/main/java/interface_adapter/query/QueryViewModel.java index a0695bef6..54c56cff8 100644 --- a/src/main/java/interface_adapter/query/QueryViewModel.java +++ b/src/main/java/interface_adapter/query/QueryViewModel.java @@ -1,24 +1,20 @@ package interface_adapter.query; +import entity.RankHistory; import interface_adapter.ViewModel; -import java.util.ArrayList; - /** * The View Model for the query view. */ public class QueryViewModel extends ViewModel { public QueryViewModel() { - super("Query"); + super("query"); setState(new QueryState()); } - public String getUsername() { - return getState().getUsername(); + public RankHistory getRankHistoryList() { + return getState().getRankHistoryList(); } - public ArrayList getRankHistory() { - return getState().getRankHistory(); - } } From 5e84327267c874d1688b31b9be137a56e8b8802f Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Mon, 2 Dec 2024 08:25:05 -0500 Subject: [PATCH 102/125] Update use cases and query view. --- .../data_access/QueryDataAccessObject.java | 3 +- .../query/QueryController.java | 2 - .../query/QueryPresenter.java | 3 +- .../use_case/query/DataAccessException.java | 10 +++ .../query/QueryDataAccessInterface.java | 12 ++++ .../use_case/query/QueryInputBoundary.java | 13 ++-- .../java/use_case/query/QueryInputData.java | 15 ----- .../java/use_case/query/QueryInteractor.java | 26 +++++++- .../use_case/query/QueryOutputBoundary.java | 16 +++++ .../java/use_case/query/QueryOutputData.java | 28 -------- src/main/java/view/QueryView.java | 64 +++++++++++++++++++ 11 files changed, 133 insertions(+), 59 deletions(-) create mode 100644 src/main/java/use_case/query/DataAccessException.java delete mode 100644 src/main/java/use_case/query/QueryInputData.java delete mode 100644 src/main/java/use_case/query/QueryOutputData.java create mode 100644 src/main/java/view/QueryView.java diff --git a/src/main/java/data_access/QueryDataAccessObject.java b/src/main/java/data_access/QueryDataAccessObject.java index 4fc45c3bf..f52edd2c0 100644 --- a/src/main/java/data_access/QueryDataAccessObject.java +++ b/src/main/java/data_access/QueryDataAccessObject.java @@ -6,12 +6,11 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import use_case.query.QueryDataAccessInterface; /** * The DAO for accessing user rank history stored in the database. */ -public class QueryDataAccessObject implements QueryDataAccessInterface { +public class QueryDataAccessObject { @Override public RankHistory showRankHistory(String username) { diff --git a/src/main/java/interface_adapter/query/QueryController.java b/src/main/java/interface_adapter/query/QueryController.java index 8bb2cadd6..2af47a403 100644 --- a/src/main/java/interface_adapter/query/QueryController.java +++ b/src/main/java/interface_adapter/query/QueryController.java @@ -1,7 +1,5 @@ package interface_adapter.query; -import use_case.query.QueryInputBoundary; - /** * The controller for the query use case. */ diff --git a/src/main/java/interface_adapter/query/QueryPresenter.java b/src/main/java/interface_adapter/query/QueryPresenter.java index aa5b152a4..746b6a42d 100644 --- a/src/main/java/interface_adapter/query/QueryPresenter.java +++ b/src/main/java/interface_adapter/query/QueryPresenter.java @@ -2,12 +2,11 @@ import entity.RankHistory; import interface_adapter.ViewManagerModel; -import use_case.query.QueryOutputBoundary; /** * The presenter for query viewing. */ -public class QueryPresenter implements QueryOutputBoundary { +public class QueryPresenter { private final QueryViewModel queryViewModel; private final ViewManagerModel viewManagerModel; diff --git a/src/main/java/use_case/query/DataAccessException.java b/src/main/java/use_case/query/DataAccessException.java new file mode 100644 index 000000000..a70b2edfb --- /dev/null +++ b/src/main/java/use_case/query/DataAccessException.java @@ -0,0 +1,10 @@ +package use_case.query; + +/** + * Exception thrown when there is an error with accessing data. + */ +public class DataAccessException extends Exception { + public DataAccessException(String string) { + super(string); + } +} diff --git a/src/main/java/use_case/query/QueryDataAccessInterface.java b/src/main/java/use_case/query/QueryDataAccessInterface.java index dc6ec1f12..cee7dad35 100644 --- a/src/main/java/use_case/query/QueryDataAccessInterface.java +++ b/src/main/java/use_case/query/QueryDataAccessInterface.java @@ -1,4 +1,16 @@ package use_case.query; +import entity.RankHistory; + +/** + * Interface for the QueryDAO. + */ public interface QueryDataAccessInterface { + + /** + * Saves a rank history for a given user. + * @param username the query user's name. + * @return the rank history of the user. + */ + RankHistory showRankHistory(String username); } diff --git a/src/main/java/use_case/query/QueryInputBoundary.java b/src/main/java/use_case/query/QueryInputBoundary.java index 743cc81ea..2a75ad8dd 100644 --- a/src/main/java/use_case/query/QueryInputBoundary.java +++ b/src/main/java/use_case/query/QueryInputBoundary.java @@ -1,18 +1,13 @@ package use_case.query; /** - * Input Boundary for actions which are related to searching user. + * The Input Boundary for query use cases. */ public interface QueryInputBoundary { /** - * Executes the search User use case. - * @param username the input data + * Executes the query use case. + * @param username the user . */ void execute(String username); - - /** - * Executes the switch to login view use case. - */ - void switchToLoginView(); -} \ No newline at end of file +} diff --git a/src/main/java/use_case/query/QueryInputData.java b/src/main/java/use_case/query/QueryInputData.java deleted file mode 100644 index 69b1f8694..000000000 --- a/src/main/java/use_case/query/QueryInputData.java +++ /dev/null @@ -1,15 +0,0 @@ -package use_case.query; - -/** - * The Input Data for the SearchUser use case. - */ - -public class QueryInputData { - private final String username; - - public QueryInputData(String username) { - this.username = username; } - - public String getUsername() { - return username; } -} diff --git a/src/main/java/use_case/query/QueryInteractor.java b/src/main/java/use_case/query/QueryInteractor.java index dd3bea5eb..da198fed1 100644 --- a/src/main/java/use_case/query/QueryInteractor.java +++ b/src/main/java/use_case/query/QueryInteractor.java @@ -1,4 +1,28 @@ package use_case.query; -public class QueryInteractor { +import entity.RankHistory; + +/** + * The Query Interactor. + */ +public class QueryInteractor implements QueryInputBoundary { + private final QueryDataAccessInterface queryDataAccessInterface; + private final QueryOutputBoundary queryOutputBoundary; + + public QueryInteractor(QueryDataAccessInterface queryDataAccessInterface, + QueryOutputBoundary queryOutputBoundary) { + this.queryDataAccessInterface = queryDataAccessInterface; + this.queryOutputBoundary = queryOutputBoundary; + } + + /** + * Executes the query use case. + * + * @param username the user. + */ + @Override + public void execute(String username) { + final RankHistory rankHistoryList = queryDataAccessInterface.showRankHistory(username); + queryOutputBoundary.prepareSuccessView(rankHistoryList); + } } diff --git a/src/main/java/use_case/query/QueryOutputBoundary.java b/src/main/java/use_case/query/QueryOutputBoundary.java index aad4accd5..3de9ac93a 100644 --- a/src/main/java/use_case/query/QueryOutputBoundary.java +++ b/src/main/java/use_case/query/QueryOutputBoundary.java @@ -1,4 +1,20 @@ package use_case.query; +import entity.RankHistory; + +/** + * The output boundary for the query Use Case. + */ public interface QueryOutputBoundary { + /** + * Prepares the success view for the query related Use Cases. + * @param rankHistoryList the rank history data. + */ + void prepareSuccessView(RankHistory rankHistoryList); + + /** + * Prepares the failure view for the query related Use Cases. + * @param errorMessage the explanation of the failure + */ + void prepareFailView(String errorMessage); } diff --git a/src/main/java/use_case/query/QueryOutputData.java b/src/main/java/use_case/query/QueryOutputData.java deleted file mode 100644 index a5d39eaac..000000000 --- a/src/main/java/use_case/query/QueryOutputData.java +++ /dev/null @@ -1,28 +0,0 @@ -package use_case.query; - -import java.util.ArrayList; - -/** - * Output Data for the ShowProfile Use case. - */ -public class QueryOutputData { - - private final String username; - private final ArrayList rankHistory; - private final boolean useCaseSucceeded; - - public QueryOutputData(String username, ArrayList rankHistory, boolean useCaseSucceeded) { - this.username = username; - this.rankHistory = rankHistory; - this.useCaseSucceeded = useCaseSucceeded; - } - - public ArrayList getRankHistory() { - return rankHistory; - } - - public String getUsername() { - return username; - } - -} diff --git a/src/main/java/view/QueryView.java b/src/main/java/view/QueryView.java new file mode 100644 index 000000000..0a9fb5b62 --- /dev/null +++ b/src/main/java/view/QueryView.java @@ -0,0 +1,64 @@ +package view; + +import entity.RankHistory; +import interface_adapter.ViewManagerModel; +import interface_adapter.query.QueryViewModel; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/** + * The view of user profile. + */ +public class QueryView extends JPanel implements ActionListener, PropertyChangeListener { + + private final String viewName = "query"; + private final QueryViewModel queryViewModel; + private final JPanel contentPanel; + + public QueryView(ViewManagerModel viewManagerModel, QueryViewModel queryViewModel) { + this.queryViewModel = queryViewModel; + this.queryViewModel.addPropertyChangeListener(this); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + final JLabel title = new JLabel("Rank History"); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + + final JScrollPane scrollPane = new JScrollPane(); + + contentPanel = new JPanel(); + contentPanel.setLayout(new GridLayout(0, 1)); + + scrollPane.setViewportView(contentPanel); + + this.add(title); + this.add(scrollPane); + + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + final RankHistory rankHistory = queryViewModel.getRankHistoryList(); + for (int i = 0; i < rankHistory.getRanks().size(); i++) { + contentPanel.add(new JLabel(rankHistory.getRanks().get(i).toString())); + } + } + + /** + * React to a button click that results in evt. + * @param evt the ActionEvent to react to + */ + public void actionPerformed(ActionEvent evt) { + + } + + public String getViewName() { + return viewName; + } + +} From beadcd16ac9cd405b75eb52e7aee647a00ec8c9a Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Mon, 2 Dec 2024 09:06:08 -0500 Subject: [PATCH 103/125] Update main_ck with query view. --- src/main/java/app/MainChessAPP.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/app/MainChessAPP.java b/src/main/java/app/MainChessAPP.java index f338a9fd7..11ceb9558 100644 --- a/src/main/java/app/MainChessAPP.java +++ b/src/main/java/app/MainChessAPP.java @@ -8,11 +8,13 @@ import data_access.ChessDataAccessObject; import data_access.UserDataAccessObject; +import data_access.QueryDataAccessObject; import interface_adapter.ViewManagerModel; import interface_adapter.logged_in.LoggedInViewModel; import interface_adapter.login.LoginViewModel; import interface_adapter.showProfile.ShowProfileViewModel; import interface_adapter.signup.SignupViewModel; +import interface_adapter.query.QueryViewModel; import view.*; /** @@ -40,21 +42,25 @@ public static void main(String[] args) { final LoggedInViewModel loggedInViewModel = new LoggedInViewModel(); final SignupViewModel signupViewModel = new SignupViewModel(); final ShowProfileViewModel showProfileViewModel = new ShowProfileViewModel(); + final QueryViewModel queryViewModel = new QueryViewModel(); final UserDataAccessObject userDataAccessObject = new UserDataAccessObject(); - - final SignupView signupView = SignupUseCaseFactory.create(viewManagerModel, loginViewModel, + final QueryDataAccessObject queryDataAccessObject = new QueryDataAccessObject(); + final SignupView signupView = SignupApp.create(viewManagerModel, loginViewModel, signupViewModel, userDataAccessObject); final LoginView loginView = LoginUseCaseFactory.create(viewManagerModel, loginViewModel, loggedInViewModel, userDataAccessObject, signupViewModel); final LoggedInView loggedInView = ShowProfileUseCaseFactory.create(viewManagerModel, loggedInViewModel, signupViewModel, showProfileViewModel, userDataAccessObject); final ProfileView profileView = new ProfileView(viewManagerModel, showProfileViewModel); + // final LoggedInView loggedInView = new LoggedInView(viewManagerModel, loggedInViewModel); + final QueryView queryView = new QueryView(viewManagerModel, queryViewModel); views.add(signupView, signupView.getViewName()); views.add(loginView, loginView.getViewName()); views.add(loggedInView, loggedInView.getViewName()); views.add(profileView, profileView.getViewName()); + views.add(queryView, queryView.getViewName()); final ChessAppBuilder chessAppBuilder = new ChessAppBuilder(); chessAppBuilder.addChessDAO(new ChessDataAccessObject()) From 58b188ec87c8b969dc024d930c48eea9292872ea Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Mon, 2 Dec 2024 10:00:57 -0500 Subject: [PATCH 104/125] Update LoggedInView.java and ShowProfileUseCaseFactory.java with query view. --- .../java/app/ShowProfileUseCaseFactory.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/java/app/ShowProfileUseCaseFactory.java b/src/main/java/app/ShowProfileUseCaseFactory.java index 039b466ec..62a02ccf6 100644 --- a/src/main/java/app/ShowProfileUseCaseFactory.java +++ b/src/main/java/app/ShowProfileUseCaseFactory.java @@ -7,6 +7,9 @@ import interface_adapter.showProfile.ShowProfileController; import interface_adapter.showProfile.ShowProfilePresenter; import interface_adapter.showProfile.ShowProfileViewModel; +import interface_adapter.query.QueryController; +import interface_adapter.query.QueryPresenter; +import interface_adapter.query.QueryViewModel; import interface_adapter.signup.SignupViewModel; import use_case.logged_in.LoggedInInputBoundary; import use_case.logged_in.LoggedInInteractor; @@ -15,6 +18,11 @@ import use_case.showProfile.ShowProfileInteractor; import use_case.showProfile.ShowProfileOutputBoundary; import use_case.showProfile.ShowProfileUserDataAccessInterface; +import use_case.query.QueryDataAccessInterface; +import use_case.query.QueryInputBoundary; +import use_case.query.QueryInteractor; +import use_case.query.QueryOutputBoundary; + import view.LoggedInView; /** @@ -35,6 +43,8 @@ private ShowProfileUseCaseFactory() { * @param signupViewModel the signupViewModel * @param showProfileViewModel the showProfileViewModel * @param userDataAccessObject the ChangePasswordUserDataAccessInterface to inject into the LoggedInView + * @param queryViewModel the QueryViewModel to inject into the LoggedInView + * @param queryDataAccessObject the Query DataAccessObject * @return the LoggedInView created for the provided input classes */ public static LoggedInView create( @@ -42,12 +52,19 @@ public static LoggedInView create( LoggedInViewModel loggedInViewModel, SignupViewModel signupViewModel, ShowProfileViewModel showProfileViewModel, - ShowProfileUserDataAccessInterface userDataAccessObject) { + QueryViewModel queryViewModel, + ShowProfileUserDataAccessInterface userDataAccessObject, + QueryDataAccessInterface queryDataAccessObject) { final ShowProfileController showProfileController = createShowProfileUseCase(viewManagerModel, loggedInViewModel, showProfileViewModel, userDataAccessObject); + final QueryOutputBoundary queryOutputBoundary = new QueryPresenter(queryViewModel, viewManagerModel); + final QueryInputBoundary queryInputInteractor = new QueryInteractor(queryDataAccessObject, queryOutputBoundary); + final QueryController queryController = new QueryController(queryInputInteractor); + + return new LoggedInView(viewManagerModel, loggedInViewModel, showProfileController, queryController); final LoggedInController loggedInController = createLoggedInUseCase(viewManagerModel, loggedInViewModel, signupViewModel); From c773a610592d9d20574b2a2172e55e8ae0fe9c13 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Mon, 2 Dec 2024 11:35:37 -0500 Subject: [PATCH 105/125] Fixing bugs. --- src/main/java/app/MainChessAPP.java | 1 + src/main/java/app/ShowProfileUseCaseFactory.java | 11 ++++++++++- src/main/java/data_access/QueryDataAccessObject.java | 3 ++- .../java/interface_adapter/query/QueryController.java | 2 ++ .../java/interface_adapter/query/QueryPresenter.java | 3 ++- src/main/java/view/LoggedInView.java | 2 +- 6 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/app/MainChessAPP.java b/src/main/java/app/MainChessAPP.java index 11ceb9558..bb39ddc4b 100644 --- a/src/main/java/app/MainChessAPP.java +++ b/src/main/java/app/MainChessAPP.java @@ -52,6 +52,7 @@ public static void main(String[] args) { loggedInViewModel, userDataAccessObject, signupViewModel); final LoggedInView loggedInView = ShowProfileUseCaseFactory.create(viewManagerModel, loggedInViewModel, signupViewModel, showProfileViewModel, userDataAccessObject); + showProfileViewModel, queryViewModel, userDataAccessObject, queryDataAccessObject); final ProfileView profileView = new ProfileView(viewManagerModel, showProfileViewModel); // final LoggedInView loggedInView = new LoggedInView(viewManagerModel, loggedInViewModel); final QueryView queryView = new QueryView(viewManagerModel, queryViewModel); diff --git a/src/main/java/app/ShowProfileUseCaseFactory.java b/src/main/java/app/ShowProfileUseCaseFactory.java index 62a02ccf6..95bd4c6e4 100644 --- a/src/main/java/app/ShowProfileUseCaseFactory.java +++ b/src/main/java/app/ShowProfileUseCaseFactory.java @@ -18,13 +18,21 @@ import use_case.showProfile.ShowProfileInteractor; import use_case.showProfile.ShowProfileOutputBoundary; import use_case.showProfile.ShowProfileUserDataAccessInterface; +import interface_adapter.showProfile.ShowProfileController; +import interface_adapter.showProfile.ShowProfilePresenter; +import interface_adapter.showProfile.ShowProfileViewModel; import use_case.query.QueryDataAccessInterface; import use_case.query.QueryInputBoundary; import use_case.query.QueryInteractor; import use_case.query.QueryOutputBoundary; - +import use_case.showProfile.ShowProfileInputBoundary; +import use_case.showProfile.ShowProfileInteractor; +import use_case.showProfile.ShowProfileOutputBoundary; +import use_case.showProfile.ShowProfileUserDataAccessInterface; import view.LoggedInView; +import javax.management.Query; + /** * This class contains the static factory function for creating the LoggedInView. */ @@ -42,6 +50,7 @@ private ShowProfileUseCaseFactory() { * @param loggedInViewModel the loggedInViewModel to inject into the LoggedInView * @param signupViewModel the signupViewModel * @param showProfileViewModel the showProfileViewModel + * @param showProfileViewModel fsf * @param userDataAccessObject the ChangePasswordUserDataAccessInterface to inject into the LoggedInView * @param queryViewModel the QueryViewModel to inject into the LoggedInView * @param queryDataAccessObject the Query DataAccessObject diff --git a/src/main/java/data_access/QueryDataAccessObject.java b/src/main/java/data_access/QueryDataAccessObject.java index f52edd2c0..4fc45c3bf 100644 --- a/src/main/java/data_access/QueryDataAccessObject.java +++ b/src/main/java/data_access/QueryDataAccessObject.java @@ -6,11 +6,12 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; +import use_case.query.QueryDataAccessInterface; /** * The DAO for accessing user rank history stored in the database. */ -public class QueryDataAccessObject { +public class QueryDataAccessObject implements QueryDataAccessInterface { @Override public RankHistory showRankHistory(String username) { diff --git a/src/main/java/interface_adapter/query/QueryController.java b/src/main/java/interface_adapter/query/QueryController.java index 2af47a403..8bb2cadd6 100644 --- a/src/main/java/interface_adapter/query/QueryController.java +++ b/src/main/java/interface_adapter/query/QueryController.java @@ -1,5 +1,7 @@ package interface_adapter.query; +import use_case.query.QueryInputBoundary; + /** * The controller for the query use case. */ diff --git a/src/main/java/interface_adapter/query/QueryPresenter.java b/src/main/java/interface_adapter/query/QueryPresenter.java index 746b6a42d..aa5b152a4 100644 --- a/src/main/java/interface_adapter/query/QueryPresenter.java +++ b/src/main/java/interface_adapter/query/QueryPresenter.java @@ -2,11 +2,12 @@ import entity.RankHistory; import interface_adapter.ViewManagerModel; +import use_case.query.QueryOutputBoundary; /** * The presenter for query viewing. */ -public class QueryPresenter { +public class QueryPresenter implements QueryOutputBoundary { private final QueryViewModel queryViewModel; private final ViewManagerModel viewManagerModel; diff --git a/src/main/java/view/LoggedInView.java b/src/main/java/view/LoggedInView.java index 01659fbca..9b550476c 100644 --- a/src/main/java/view/LoggedInView.java +++ b/src/main/java/view/LoggedInView.java @@ -107,7 +107,7 @@ public void actionPerformed(ActionEvent evt) { if (evt.getSource().equals(showRankHistory)) { final LoggedInState currentState = loggedInViewModel.getState(); - QueryController.execute( + queryController.execute( currentState.getUsername() ); } From d61e92dffc02aedac2080434cb529d9205687b52 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Tue, 3 Dec 2024 01:04:58 -0500 Subject: [PATCH 106/125] . --- src/main/java/app/MainChessAPP.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/app/MainChessAPP.java b/src/main/java/app/MainChessAPP.java index bb39ddc4b..cdd5c9da1 100644 --- a/src/main/java/app/MainChessAPP.java +++ b/src/main/java/app/MainChessAPP.java @@ -9,9 +9,11 @@ import data_access.ChessDataAccessObject; import data_access.UserDataAccessObject; import data_access.QueryDataAccessObject; +import data_access.UserDataAccessObject; import interface_adapter.ViewManagerModel; import interface_adapter.logged_in.LoggedInViewModel; import interface_adapter.login.LoginViewModel; +import interface_adapter.query.QueryViewModel; import interface_adapter.showProfile.ShowProfileViewModel; import interface_adapter.signup.SignupViewModel; import interface_adapter.query.QueryViewModel; From 997bdb08d977a3625ed493988534b0bd03683f7c Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Tue, 3 Dec 2024 10:31:12 -0500 Subject: [PATCH 107/125] . --- src/main/java/app/MainChessAPP.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/app/MainChessAPP.java b/src/main/java/app/MainChessAPP.java index cdd5c9da1..2f9c87e7b 100644 --- a/src/main/java/app/MainChessAPP.java +++ b/src/main/java/app/MainChessAPP.java @@ -9,14 +9,12 @@ import data_access.ChessDataAccessObject; import data_access.UserDataAccessObject; import data_access.QueryDataAccessObject; -import data_access.UserDataAccessObject; import interface_adapter.ViewManagerModel; import interface_adapter.logged_in.LoggedInViewModel; import interface_adapter.login.LoginViewModel; import interface_adapter.query.QueryViewModel; import interface_adapter.showProfile.ShowProfileViewModel; import interface_adapter.signup.SignupViewModel; -import interface_adapter.query.QueryViewModel; import view.*; /** From 015d9f0d35ad4d9111ac361047887ad586c3d2f1 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Tue, 3 Dec 2024 10:41:39 -0500 Subject: [PATCH 108/125] Rebase origin main. --- src/main/java/app/MainChessAPP.java | 18 ++---- .../java/app/ShowProfileUseCaseFactory.java | 34 +++------- .../data_access/QueryDataAccessObject.java | 60 ----------------- src/main/java/entity/RankHistory.java | 64 ------------------- .../query/QueryController.java | 23 ------- .../query/QueryPresenter.java | 46 ------------- .../interface_adapter/query/QueryState.java | 22 ------- .../query/QueryViewModel.java | 20 ------ .../use_case/query/DataAccessException.java | 10 --- .../query/QueryDataAccessInterface.java | 16 ----- .../use_case/query/QueryInputBoundary.java | 13 ---- .../java/use_case/query/QueryInteractor.java | 28 -------- .../use_case/query/QueryOutputBoundary.java | 20 ------ src/main/java/view/LoggedInView.java | 31 +-------- src/main/java/view/QueryView.java | 64 ------------------- 15 files changed, 16 insertions(+), 453 deletions(-) delete mode 100644 src/main/java/data_access/QueryDataAccessObject.java delete mode 100644 src/main/java/entity/RankHistory.java delete mode 100644 src/main/java/interface_adapter/query/QueryController.java delete mode 100644 src/main/java/interface_adapter/query/QueryPresenter.java delete mode 100644 src/main/java/interface_adapter/query/QueryState.java delete mode 100644 src/main/java/interface_adapter/query/QueryViewModel.java delete mode 100644 src/main/java/use_case/query/DataAccessException.java delete mode 100644 src/main/java/use_case/query/QueryDataAccessInterface.java delete mode 100644 src/main/java/use_case/query/QueryInputBoundary.java delete mode 100644 src/main/java/use_case/query/QueryInteractor.java delete mode 100644 src/main/java/use_case/query/QueryOutputBoundary.java delete mode 100644 src/main/java/view/QueryView.java diff --git a/src/main/java/app/MainChessAPP.java b/src/main/java/app/MainChessAPP.java index 503242f9b..f338a9fd7 100644 --- a/src/main/java/app/MainChessAPP.java +++ b/src/main/java/app/MainChessAPP.java @@ -8,19 +8,17 @@ import data_access.ChessDataAccessObject; import data_access.UserDataAccessObject; -import data_access.QueryDataAccessObject; import interface_adapter.ViewManagerModel; import interface_adapter.logged_in.LoggedInViewModel; import interface_adapter.login.LoginViewModel; import interface_adapter.showProfile.ShowProfileViewModel; import interface_adapter.signup.SignupViewModel; -import interface_adapter.query.QueryViewModel; import view.*; /** * Main that activates login page. */ -public class Main_ck { +public class MainChessAPP { /** * The main method for starting the program with an external database used to persist user data. @@ -42,29 +40,23 @@ public static void main(String[] args) { final LoggedInViewModel loggedInViewModel = new LoggedInViewModel(); final SignupViewModel signupViewModel = new SignupViewModel(); final ShowProfileViewModel showProfileViewModel = new ShowProfileViewModel(); - final QueryViewModel queryViewModel = new QueryViewModel(); final UserDataAccessObject userDataAccessObject = new UserDataAccessObject(); - final QueryDataAccessObject queryDataAccessObject = new QueryDataAccessObject(); - final SignupView signupView = SignupApp.create(viewManagerModel, loginViewModel, + final SignupView signupView = SignupUseCaseFactory.create(viewManagerModel, loginViewModel, signupViewModel, userDataAccessObject); final LoginView loginView = LoginUseCaseFactory.create(viewManagerModel, loginViewModel, - loggedInViewModel, userDataAccessObject); + loggedInViewModel, userDataAccessObject, signupViewModel); final LoggedInView loggedInView = ShowProfileUseCaseFactory.create(viewManagerModel, loggedInViewModel, - showProfileViewModel, queryViewModel, userDataAccessObject, queryDataAccessObject); - + signupViewModel, showProfileViewModel, userDataAccessObject); final ProfileView profileView = new ProfileView(viewManagerModel, showProfileViewModel); - // final LoggedInView loggedInView = new LoggedInView(viewManagerModel, loggedInViewModel); - final QueryView queryView = new QueryView(viewManagerModel, queryViewModel); views.add(signupView, signupView.getViewName()); views.add(loginView, loginView.getViewName()); views.add(loggedInView, loggedInView.getViewName()); views.add(profileView, profileView.getViewName()); - views.add(queryView, queryView.getViewName()); - final CK_ChessAppBuilder chessAppBuilder = new CK_ChessAppBuilder(); + final ChessAppBuilder chessAppBuilder = new ChessAppBuilder(); chessAppBuilder.addChessDAO(new ChessDataAccessObject()) .addMoveView() .addMoveUseCase(); diff --git a/src/main/java/app/ShowProfileUseCaseFactory.java b/src/main/java/app/ShowProfileUseCaseFactory.java index e2dea987d..039b466ec 100644 --- a/src/main/java/app/ShowProfileUseCaseFactory.java +++ b/src/main/java/app/ShowProfileUseCaseFactory.java @@ -4,25 +4,19 @@ import interface_adapter.logged_in.LoggedInController; import interface_adapter.logged_in.LoggedInPresenter; import interface_adapter.logged_in.LoggedInViewModel; -import interface_adapter.query.QueryController; -import interface_adapter.query.QueryPresenter; -import interface_adapter.query.QueryViewModel; import interface_adapter.showProfile.ShowProfileController; import interface_adapter.showProfile.ShowProfilePresenter; import interface_adapter.showProfile.ShowProfileViewModel; -import use_case.query.QueryDataAccessInterface; -import use_case.query.QueryInputBoundary; -import use_case.query.QueryInteractor; -import use_case.query.QueryOutputBoundary; - +import interface_adapter.signup.SignupViewModel; +import use_case.logged_in.LoggedInInputBoundary; +import use_case.logged_in.LoggedInInteractor; +import use_case.logged_in.LoggedInOutputBoundary; import use_case.showProfile.ShowProfileInputBoundary; import use_case.showProfile.ShowProfileInteractor; import use_case.showProfile.ShowProfileOutputBoundary; import use_case.showProfile.ShowProfileUserDataAccessInterface; import view.LoggedInView; -import javax.management.Query; - /** * This class contains the static factory function for creating the LoggedInView. */ @@ -38,11 +32,9 @@ private ShowProfileUseCaseFactory() { * * @param viewManagerModel the ViewManagerModel to inject into the LoggedInView * @param loggedInViewModel the loggedInViewModel to inject into the LoggedInView - * @param signupViewModel - * @param showProfileViewModel + * @param signupViewModel the signupViewModel + * @param showProfileViewModel the showProfileViewModel * @param userDataAccessObject the ChangePasswordUserDataAccessInterface to inject into the LoggedInView - * @param queryViewModel the QueryViewModel to inject into the LoggedInView - * @param queryDataAccessObject the Query DataAccessObject * @return the LoggedInView created for the provided input classes */ public static LoggedInView create( @@ -50,25 +42,15 @@ public static LoggedInView create( LoggedInViewModel loggedInViewModel, SignupViewModel signupViewModel, ShowProfileViewModel showProfileViewModel, - QueryViewModel queryViewModel, - ShowProfileUserDataAccessInterface userDataAccessObject, - QueryDataAccessInterface queryDataAccessObject) { + ShowProfileUserDataAccessInterface userDataAccessObject) { final ShowProfileController showProfileController = createShowProfileUseCase(viewManagerModel, loggedInViewModel, showProfileViewModel, userDataAccessObject); - - final QueryOutputBoundary queryOutputBoundary = new QueryPresenter(queryViewModel, viewManagerModel); - final QueryInputBoundary queryInputInteractor = new QueryInteractor(queryDataAccessObject, queryOutputBoundary); - final QueryController queryController = new QueryController(queryInputInteractor); - - return new LoggedInView(viewManagerModel, loggedInViewModel, showProfileController, queryController); - final LoggedInController loggedInController = createLoggedInUseCase(viewManagerModel, loggedInViewModel, signupViewModel); - return new LoggedInView(viewManagerModel, loggedInController, loggedInViewModel, showProfileController); } @@ -90,7 +72,7 @@ private static ShowProfileController createShowProfileUseCase( private static LoggedInController createLoggedInUseCase( ViewManagerModel viewManagerModel, LoggedInViewModel loggedInViewModel, - SignupViewModel signupViewModel){ + SignupViewModel signupViewModel) { final LoggedInOutputBoundary loggedInOutputBoundary = new LoggedInPresenter(viewManagerModel, loggedInViewModel, signupViewModel); diff --git a/src/main/java/data_access/QueryDataAccessObject.java b/src/main/java/data_access/QueryDataAccessObject.java deleted file mode 100644 index 4fc45c3bf..000000000 --- a/src/main/java/data_access/QueryDataAccessObject.java +++ /dev/null @@ -1,60 +0,0 @@ -package data_access; - -import java.io.IOException; - -import entity.RankHistory; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import use_case.query.QueryDataAccessInterface; - -/** - * The DAO for accessing user rank history stored in the database. - */ -public class QueryDataAccessObject implements QueryDataAccessInterface { - @Override - public RankHistory showRankHistory(String username) { - - final RankHistory rankHistory = new RankHistory(); - - final String url = String.format("https://lichess.org/api/user/%s/rating-history", username); - final OkHttpClient client = new OkHttpClient().newBuilder().build(); - final Request request = new Request.Builder() - .url(url) - .build(); - - try (Response response = client.newCall(request).execute()) { - - final String responseBody = response.body().string(); - final com.alibaba.fastjson.JSONArray jsonArray = com.alibaba.fastjson.JSONArray.parseArray(responseBody); - - jsonArray.stream().forEach(str -> { - final com.alibaba.fastjson.JSONObject jsonObject = - com.alibaba.fastjson.JSONObject.parseObject(str.toString()); - - final String name = (String) jsonObject.get("name"); - if ("Puzzles".equals(name)) { - final Object points = jsonObject.get("points"); - final com.alibaba.fastjson.JSONArray pointarr = - com.alibaba.fastjson.JSONArray.parseArray(points.toString()); - - final Object[] objects = pointarr.toArray(); - - for (Object object : objects) { - final com.alibaba.fastjson.JSONArray ranks = - com.alibaba.fastjson.JSONArray.parseArray(object.toString()); - final int year = (Integer) ranks.get(0); - final int month = (Integer) ranks.get(1); - final int day = (Integer) ranks.get(2); - final int rank = (Integer) ranks.get(3); - rankHistory.addRankHistory(year, month, day, rank); - } - } - }); - return rankHistory; - } - catch (IOException ex) { - throw new RuntimeException(ex); - } - } -} diff --git a/src/main/java/entity/RankHistory.java b/src/main/java/entity/RankHistory.java deleted file mode 100644 index e13cd9842..000000000 --- a/src/main/java/entity/RankHistory.java +++ /dev/null @@ -1,64 +0,0 @@ -package entity; - -import java.util.ArrayList; -import java.util.List; - -/** - * The representation of user rank history for our program. - */ - -public class RankHistory { - private final List rankHistoryList; - - public RankHistory() { - this.rankHistoryList = new ArrayList<>(); - } - - public List getRanks() { - return rankHistoryList; - } - - /** - * Print the RankHistory. - */ - public void printRankHistory() { - for (Rank rank : rankHistoryList) { - System.out.println(rank); - } - } - - /** - * Add user rank for our program. - * @param year the rank year. - * @param month the rank month. - * @param day the rank day. - * @param rank the rank . - */ - public void addRankHistory(int year, int month, int day, int rank) { - final Rank rh = new Rank(year, month, day, rank); - this.rankHistoryList.add(rh); - } - - /** - * The representation of user rank for our program. - */ - public static class Rank { - private final int year; - private final int month; - private final int day; - private final int rank; - - public Rank(int year, int month, int day, int rank) { - this.year = year; - this.month = month + 1; - this.day = day; - this.rank = rank; - } - - @Override - public String toString() { - return "Year:" + year + " Month:" + month - + " Day:" + day + " Rank:" + rank; - } - } -} diff --git a/src/main/java/interface_adapter/query/QueryController.java b/src/main/java/interface_adapter/query/QueryController.java deleted file mode 100644 index 8bb2cadd6..000000000 --- a/src/main/java/interface_adapter/query/QueryController.java +++ /dev/null @@ -1,23 +0,0 @@ -package interface_adapter.query; - -import use_case.query.QueryInputBoundary; - -/** - * The controller for the query use case. - */ -public class QueryController { - - private final QueryInputBoundary queryInteractor; - - public QueryController(QueryInputBoundary queryInteractor) { - this.queryInteractor = queryInteractor; - } - - /** - * Execute the query use case. - * @param username the username of the user logging in - */ - public void execute(String username) { - queryInteractor.execute(username); - } -} diff --git a/src/main/java/interface_adapter/query/QueryPresenter.java b/src/main/java/interface_adapter/query/QueryPresenter.java deleted file mode 100644 index aa5b152a4..000000000 --- a/src/main/java/interface_adapter/query/QueryPresenter.java +++ /dev/null @@ -1,46 +0,0 @@ -package interface_adapter.query; - -import entity.RankHistory; -import interface_adapter.ViewManagerModel; -import use_case.query.QueryOutputBoundary; - -/** - * The presenter for query viewing. - */ -public class QueryPresenter implements QueryOutputBoundary { - - private final QueryViewModel queryViewModel; - private final ViewManagerModel viewManagerModel; - - public QueryPresenter(QueryViewModel queryViewModel, ViewManagerModel viewManagerModel) { - this.queryViewModel = queryViewModel; - this.viewManagerModel = viewManagerModel; - } - - /** - * Prepares the success view for the query related Use Cases. - * - * @param rankHistoryList the user rank history data. - */ - @Override - public void prepareSuccessView(RankHistory rankHistoryList) { - // On success, switch to the Query view. - final QueryState queryState = queryViewModel.getState(); - queryState.setRankHistoryList(rankHistoryList); - this.queryViewModel.setState(queryState); - this.queryViewModel.firePropertyChanged(); - - this.viewManagerModel.setState(queryViewModel.getViewName()); - this.viewManagerModel.firePropertyChanged(); - } - - /** - * Prepares the failure view for the query related Use Cases. - * - * @param errorMessage the explanation of the failure - */ - @Override - public void prepareFailView(String errorMessage) { - - } -} diff --git a/src/main/java/interface_adapter/query/QueryState.java b/src/main/java/interface_adapter/query/QueryState.java deleted file mode 100644 index 66ce0bef6..000000000 --- a/src/main/java/interface_adapter/query/QueryState.java +++ /dev/null @@ -1,22 +0,0 @@ -package interface_adapter.query; - -import entity.RankHistory; - -/** - * The State information representing the query user. - */ -public class QueryState { - private RankHistory rankHistoryList; - - public QueryState() { - - } - - public void setRankHistoryList(RankHistory rankHistoryList) { - this.rankHistoryList = rankHistoryList; - } - - public RankHistory getRankHistoryList() { - return rankHistoryList; - } -} diff --git a/src/main/java/interface_adapter/query/QueryViewModel.java b/src/main/java/interface_adapter/query/QueryViewModel.java deleted file mode 100644 index 54c56cff8..000000000 --- a/src/main/java/interface_adapter/query/QueryViewModel.java +++ /dev/null @@ -1,20 +0,0 @@ -package interface_adapter.query; - -import entity.RankHistory; -import interface_adapter.ViewModel; - -/** - * The View Model for the query view. - */ -public class QueryViewModel extends ViewModel { - - public QueryViewModel() { - super("query"); - setState(new QueryState()); - } - - public RankHistory getRankHistoryList() { - return getState().getRankHistoryList(); - } - -} diff --git a/src/main/java/use_case/query/DataAccessException.java b/src/main/java/use_case/query/DataAccessException.java deleted file mode 100644 index a70b2edfb..000000000 --- a/src/main/java/use_case/query/DataAccessException.java +++ /dev/null @@ -1,10 +0,0 @@ -package use_case.query; - -/** - * Exception thrown when there is an error with accessing data. - */ -public class DataAccessException extends Exception { - public DataAccessException(String string) { - super(string); - } -} diff --git a/src/main/java/use_case/query/QueryDataAccessInterface.java b/src/main/java/use_case/query/QueryDataAccessInterface.java deleted file mode 100644 index cee7dad35..000000000 --- a/src/main/java/use_case/query/QueryDataAccessInterface.java +++ /dev/null @@ -1,16 +0,0 @@ -package use_case.query; - -import entity.RankHistory; - -/** - * Interface for the QueryDAO. - */ -public interface QueryDataAccessInterface { - - /** - * Saves a rank history for a given user. - * @param username the query user's name. - * @return the rank history of the user. - */ - RankHistory showRankHistory(String username); -} diff --git a/src/main/java/use_case/query/QueryInputBoundary.java b/src/main/java/use_case/query/QueryInputBoundary.java deleted file mode 100644 index 2a75ad8dd..000000000 --- a/src/main/java/use_case/query/QueryInputBoundary.java +++ /dev/null @@ -1,13 +0,0 @@ -package use_case.query; - -/** - * The Input Boundary for query use cases. - */ -public interface QueryInputBoundary { - - /** - * Executes the query use case. - * @param username the user . - */ - void execute(String username); -} diff --git a/src/main/java/use_case/query/QueryInteractor.java b/src/main/java/use_case/query/QueryInteractor.java deleted file mode 100644 index da198fed1..000000000 --- a/src/main/java/use_case/query/QueryInteractor.java +++ /dev/null @@ -1,28 +0,0 @@ -package use_case.query; - -import entity.RankHistory; - -/** - * The Query Interactor. - */ -public class QueryInteractor implements QueryInputBoundary { - private final QueryDataAccessInterface queryDataAccessInterface; - private final QueryOutputBoundary queryOutputBoundary; - - public QueryInteractor(QueryDataAccessInterface queryDataAccessInterface, - QueryOutputBoundary queryOutputBoundary) { - this.queryDataAccessInterface = queryDataAccessInterface; - this.queryOutputBoundary = queryOutputBoundary; - } - - /** - * Executes the query use case. - * - * @param username the user. - */ - @Override - public void execute(String username) { - final RankHistory rankHistoryList = queryDataAccessInterface.showRankHistory(username); - queryOutputBoundary.prepareSuccessView(rankHistoryList); - } -} diff --git a/src/main/java/use_case/query/QueryOutputBoundary.java b/src/main/java/use_case/query/QueryOutputBoundary.java deleted file mode 100644 index 3de9ac93a..000000000 --- a/src/main/java/use_case/query/QueryOutputBoundary.java +++ /dev/null @@ -1,20 +0,0 @@ -package use_case.query; - -import entity.RankHistory; - -/** - * The output boundary for the query Use Case. - */ -public interface QueryOutputBoundary { - /** - * Prepares the success view for the query related Use Cases. - * @param rankHistoryList the rank history data. - */ - void prepareSuccessView(RankHistory rankHistoryList); - - /** - * Prepares the failure view for the query related Use Cases. - * @param errorMessage the explanation of the failure - */ - void prepareFailView(String errorMessage); -} diff --git a/src/main/java/view/LoggedInView.java b/src/main/java/view/LoggedInView.java index 45b439244..f0af5108a 100644 --- a/src/main/java/view/LoggedInView.java +++ b/src/main/java/view/LoggedInView.java @@ -14,7 +14,6 @@ import interface_adapter.logged_in.LoggedInController; import interface_adapter.logged_in.LoggedInState; import interface_adapter.logged_in.LoggedInViewModel; -import interface_adapter.query.QueryController; import interface_adapter.showProfile.ShowProfileController; /** @@ -33,14 +32,12 @@ public class LoggedInView extends JPanel implements ActionListener, PropertyChan private final JButton startChess; private final JButton showProfile; - private final JButton showRankHistory; private final ShowProfileController showProfileController; - public LoggedInView(ViewManagerModel viewManagerModel, LoggedInController loggedInController, LoggedInViewModel loggedInViewModel, - ShowProfileController showProfileController, QueryController queryController) { - + public LoggedInView(ViewManagerModel viewManagerModel, LoggedInController loggedInController, + LoggedInViewModel loggedInViewModel, + ShowProfileController showProfileController) { this.loggedInController = loggedInController; - this.loggedInViewModel = loggedInViewModel; this.showProfileController = showProfileController; this.loggedInViewModel.addPropertyChangeListener(this); @@ -55,20 +52,12 @@ public LoggedInView(ViewManagerModel viewManagerModel, LoggedInController logged logOut = new JButton("Log Out"); buttons.add(logOut); - showRankHistory = new JButton("Show Rank History"); - showProfile = new JButton("Show Profile"); buttons.add(showProfile); startChess = new JButton("Start Chess Game"); buttons.add(startChess); - buttons.add(showProfile); - buttons.add(showRankHistory); - - -// logOut.addActionListener(this); - logOut.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { @@ -102,20 +91,6 @@ public void actionPerformed(ActionEvent evt) { } ); - showRankHistory.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent evt) { - if (evt.getSource().equals(showRankHistory)) { - final LoggedInState currentState = loggedInViewModel.getState(); - - queryController.execute( - currentState.getUsername() - ); - } - } - } - ); - this.add(title); this.add(usernameInfo); this.add(username); diff --git a/src/main/java/view/QueryView.java b/src/main/java/view/QueryView.java deleted file mode 100644 index 0a9fb5b62..000000000 --- a/src/main/java/view/QueryView.java +++ /dev/null @@ -1,64 +0,0 @@ -package view; - -import entity.RankHistory; -import interface_adapter.ViewManagerModel; -import interface_adapter.query.QueryViewModel; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; - -/** - * The view of user profile. - */ -public class QueryView extends JPanel implements ActionListener, PropertyChangeListener { - - private final String viewName = "query"; - private final QueryViewModel queryViewModel; - private final JPanel contentPanel; - - public QueryView(ViewManagerModel viewManagerModel, QueryViewModel queryViewModel) { - this.queryViewModel = queryViewModel; - this.queryViewModel.addPropertyChangeListener(this); - - this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - - final JLabel title = new JLabel("Rank History"); - title.setAlignmentX(Component.CENTER_ALIGNMENT); - - final JScrollPane scrollPane = new JScrollPane(); - - contentPanel = new JPanel(); - contentPanel.setLayout(new GridLayout(0, 1)); - - scrollPane.setViewportView(contentPanel); - - this.add(title); - this.add(scrollPane); - - } - - @Override - public void propertyChange(PropertyChangeEvent evt) { - final RankHistory rankHistory = queryViewModel.getRankHistoryList(); - for (int i = 0; i < rankHistory.getRanks().size(); i++) { - contentPanel.add(new JLabel(rankHistory.getRanks().get(i).toString())); - } - } - - /** - * React to a button click that results in evt. - * @param evt the ActionEvent to react to - */ - public void actionPerformed(ActionEvent evt) { - - } - - public String getViewName() { - return viewName; - } - -} From c7acae7a6fb891d00694c64db4aed791b310c7dd Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Tue, 3 Dec 2024 10:44:33 -0500 Subject: [PATCH 109/125] Add RankHistory entity. --- src/main/java/entity/RankHistory.java | 64 +++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/main/java/entity/RankHistory.java diff --git a/src/main/java/entity/RankHistory.java b/src/main/java/entity/RankHistory.java new file mode 100644 index 000000000..e13cd9842 --- /dev/null +++ b/src/main/java/entity/RankHistory.java @@ -0,0 +1,64 @@ +package entity; + +import java.util.ArrayList; +import java.util.List; + +/** + * The representation of user rank history for our program. + */ + +public class RankHistory { + private final List rankHistoryList; + + public RankHistory() { + this.rankHistoryList = new ArrayList<>(); + } + + public List getRanks() { + return rankHistoryList; + } + + /** + * Print the RankHistory. + */ + public void printRankHistory() { + for (Rank rank : rankHistoryList) { + System.out.println(rank); + } + } + + /** + * Add user rank for our program. + * @param year the rank year. + * @param month the rank month. + * @param day the rank day. + * @param rank the rank . + */ + public void addRankHistory(int year, int month, int day, int rank) { + final Rank rh = new Rank(year, month, day, rank); + this.rankHistoryList.add(rh); + } + + /** + * The representation of user rank for our program. + */ + public static class Rank { + private final int year; + private final int month; + private final int day; + private final int rank; + + public Rank(int year, int month, int day, int rank) { + this.year = year; + this.month = month + 1; + this.day = day; + this.rank = rank; + } + + @Override + public String toString() { + return "Year:" + year + " Month:" + month + + " Day:" + day + " Rank:" + rank; + } + } +} From d9d883796c3704d1cd73da8a8599e94fba88b682 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Tue, 3 Dec 2024 10:45:50 -0500 Subject: [PATCH 110/125] Add Query DAO. --- .../data_access/QueryDataAccessObject.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/main/java/data_access/QueryDataAccessObject.java diff --git a/src/main/java/data_access/QueryDataAccessObject.java b/src/main/java/data_access/QueryDataAccessObject.java new file mode 100644 index 000000000..0680dfa34 --- /dev/null +++ b/src/main/java/data_access/QueryDataAccessObject.java @@ -0,0 +1,60 @@ +package data_access; + +import entity.RankHistory; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import use_case.query.QueryDataAccessInterface; + +import java.io.IOException; + +/** + * The DAO for accessing user rank history stored in the database. + */ +public class QueryDataAccessObject implements QueryDataAccessInterface { + @Override + public RankHistory showRankHistory(String username) { + + final RankHistory rankHistory = new RankHistory(); + + final String url = String.format("https://lichess.org/api/user/%s/rating-history", username); + final OkHttpClient client = new OkHttpClient().newBuilder().build(); + final Request request = new Request.Builder() + .url(url) + .build(); + + try (Response response = client.newCall(request).execute()) { + + final String responseBody = response.body().string(); + final com.alibaba.fastjson.JSONArray jsonArray = com.alibaba.fastjson.JSONArray.parseArray(responseBody); + + jsonArray.stream().forEach(str -> { + final com.alibaba.fastjson.JSONObject jsonObject = + com.alibaba.fastjson.JSONObject.parseObject(str.toString()); + + final String name = (String) jsonObject.get("name"); + if ("Puzzles".equals(name)) { + final Object points = jsonObject.get("points"); + final com.alibaba.fastjson.JSONArray pointarr = + com.alibaba.fastjson.JSONArray.parseArray(points.toString()); + + final Object[] objects = pointarr.toArray(); + + for (Object object : objects) { + final com.alibaba.fastjson.JSONArray ranks = + com.alibaba.fastjson.JSONArray.parseArray(object.toString()); + final int year = (Integer) ranks.get(0); + final int month = (Integer) ranks.get(1); + final int day = (Integer) ranks.get(2); + final int rank = (Integer) ranks.get(3); + rankHistory.addRankHistory(year, month, day, rank); + } + } + }); + return rankHistory; + } + catch (IOException ex) { + throw new RuntimeException(ex); + } + } +} From 9b287f70cd4dcd76bfa934d996f260ac7cbef53a Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Tue, 3 Dec 2024 10:46:41 -0500 Subject: [PATCH 111/125] Add Query use case package. --- .../use_case/query/DataAccessException.java | 10 +++++++ .../query/QueryDataAccessInterface.java | 16 +++++++++++ .../use_case/query/QueryInputBoundary.java | 13 +++++++++ .../java/use_case/query/QueryInteractor.java | 28 +++++++++++++++++++ .../use_case/query/QueryOutputBoundary.java | 20 +++++++++++++ 5 files changed, 87 insertions(+) create mode 100644 src/main/java/use_case/query/DataAccessException.java create mode 100644 src/main/java/use_case/query/QueryDataAccessInterface.java create mode 100644 src/main/java/use_case/query/QueryInputBoundary.java create mode 100644 src/main/java/use_case/query/QueryInteractor.java create mode 100644 src/main/java/use_case/query/QueryOutputBoundary.java diff --git a/src/main/java/use_case/query/DataAccessException.java b/src/main/java/use_case/query/DataAccessException.java new file mode 100644 index 000000000..a70b2edfb --- /dev/null +++ b/src/main/java/use_case/query/DataAccessException.java @@ -0,0 +1,10 @@ +package use_case.query; + +/** + * Exception thrown when there is an error with accessing data. + */ +public class DataAccessException extends Exception { + public DataAccessException(String string) { + super(string); + } +} diff --git a/src/main/java/use_case/query/QueryDataAccessInterface.java b/src/main/java/use_case/query/QueryDataAccessInterface.java new file mode 100644 index 000000000..cee7dad35 --- /dev/null +++ b/src/main/java/use_case/query/QueryDataAccessInterface.java @@ -0,0 +1,16 @@ +package use_case.query; + +import entity.RankHistory; + +/** + * Interface for the QueryDAO. + */ +public interface QueryDataAccessInterface { + + /** + * Saves a rank history for a given user. + * @param username the query user's name. + * @return the rank history of the user. + */ + RankHistory showRankHistory(String username); +} diff --git a/src/main/java/use_case/query/QueryInputBoundary.java b/src/main/java/use_case/query/QueryInputBoundary.java new file mode 100644 index 000000000..2a75ad8dd --- /dev/null +++ b/src/main/java/use_case/query/QueryInputBoundary.java @@ -0,0 +1,13 @@ +package use_case.query; + +/** + * The Input Boundary for query use cases. + */ +public interface QueryInputBoundary { + + /** + * Executes the query use case. + * @param username the user . + */ + void execute(String username); +} diff --git a/src/main/java/use_case/query/QueryInteractor.java b/src/main/java/use_case/query/QueryInteractor.java new file mode 100644 index 000000000..da198fed1 --- /dev/null +++ b/src/main/java/use_case/query/QueryInteractor.java @@ -0,0 +1,28 @@ +package use_case.query; + +import entity.RankHistory; + +/** + * The Query Interactor. + */ +public class QueryInteractor implements QueryInputBoundary { + private final QueryDataAccessInterface queryDataAccessInterface; + private final QueryOutputBoundary queryOutputBoundary; + + public QueryInteractor(QueryDataAccessInterface queryDataAccessInterface, + QueryOutputBoundary queryOutputBoundary) { + this.queryDataAccessInterface = queryDataAccessInterface; + this.queryOutputBoundary = queryOutputBoundary; + } + + /** + * Executes the query use case. + * + * @param username the user. + */ + @Override + public void execute(String username) { + final RankHistory rankHistoryList = queryDataAccessInterface.showRankHistory(username); + queryOutputBoundary.prepareSuccessView(rankHistoryList); + } +} diff --git a/src/main/java/use_case/query/QueryOutputBoundary.java b/src/main/java/use_case/query/QueryOutputBoundary.java new file mode 100644 index 000000000..3de9ac93a --- /dev/null +++ b/src/main/java/use_case/query/QueryOutputBoundary.java @@ -0,0 +1,20 @@ +package use_case.query; + +import entity.RankHistory; + +/** + * The output boundary for the query Use Case. + */ +public interface QueryOutputBoundary { + /** + * Prepares the success view for the query related Use Cases. + * @param rankHistoryList the rank history data. + */ + void prepareSuccessView(RankHistory rankHistoryList); + + /** + * Prepares the failure view for the query related Use Cases. + * @param errorMessage the explanation of the failure + */ + void prepareFailView(String errorMessage); +} From e686d2bbec89dcf8c88af4a9caf67cdf7bcf5b94 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Tue, 3 Dec 2024 10:47:49 -0500 Subject: [PATCH 112/125] Add Query interface_adapter package. --- .../query/QueryController.java | 23 ++++++++++ .../query/QueryPresenter.java | 46 +++++++++++++++++++ .../interface_adapter/query/QueryState.java | 22 +++++++++ .../query/QueryViewModel.java | 20 ++++++++ 4 files changed, 111 insertions(+) create mode 100644 src/main/java/interface_adapter/query/QueryController.java create mode 100644 src/main/java/interface_adapter/query/QueryPresenter.java create mode 100644 src/main/java/interface_adapter/query/QueryState.java create mode 100644 src/main/java/interface_adapter/query/QueryViewModel.java diff --git a/src/main/java/interface_adapter/query/QueryController.java b/src/main/java/interface_adapter/query/QueryController.java new file mode 100644 index 000000000..8bb2cadd6 --- /dev/null +++ b/src/main/java/interface_adapter/query/QueryController.java @@ -0,0 +1,23 @@ +package interface_adapter.query; + +import use_case.query.QueryInputBoundary; + +/** + * The controller for the query use case. + */ +public class QueryController { + + private final QueryInputBoundary queryInteractor; + + public QueryController(QueryInputBoundary queryInteractor) { + this.queryInteractor = queryInteractor; + } + + /** + * Execute the query use case. + * @param username the username of the user logging in + */ + public void execute(String username) { + queryInteractor.execute(username); + } +} diff --git a/src/main/java/interface_adapter/query/QueryPresenter.java b/src/main/java/interface_adapter/query/QueryPresenter.java new file mode 100644 index 000000000..aa5b152a4 --- /dev/null +++ b/src/main/java/interface_adapter/query/QueryPresenter.java @@ -0,0 +1,46 @@ +package interface_adapter.query; + +import entity.RankHistory; +import interface_adapter.ViewManagerModel; +import use_case.query.QueryOutputBoundary; + +/** + * The presenter for query viewing. + */ +public class QueryPresenter implements QueryOutputBoundary { + + private final QueryViewModel queryViewModel; + private final ViewManagerModel viewManagerModel; + + public QueryPresenter(QueryViewModel queryViewModel, ViewManagerModel viewManagerModel) { + this.queryViewModel = queryViewModel; + this.viewManagerModel = viewManagerModel; + } + + /** + * Prepares the success view for the query related Use Cases. + * + * @param rankHistoryList the user rank history data. + */ + @Override + public void prepareSuccessView(RankHistory rankHistoryList) { + // On success, switch to the Query view. + final QueryState queryState = queryViewModel.getState(); + queryState.setRankHistoryList(rankHistoryList); + this.queryViewModel.setState(queryState); + this.queryViewModel.firePropertyChanged(); + + this.viewManagerModel.setState(queryViewModel.getViewName()); + this.viewManagerModel.firePropertyChanged(); + } + + /** + * Prepares the failure view for the query related Use Cases. + * + * @param errorMessage the explanation of the failure + */ + @Override + public void prepareFailView(String errorMessage) { + + } +} diff --git a/src/main/java/interface_adapter/query/QueryState.java b/src/main/java/interface_adapter/query/QueryState.java new file mode 100644 index 000000000..66ce0bef6 --- /dev/null +++ b/src/main/java/interface_adapter/query/QueryState.java @@ -0,0 +1,22 @@ +package interface_adapter.query; + +import entity.RankHistory; + +/** + * The State information representing the query user. + */ +public class QueryState { + private RankHistory rankHistoryList; + + public QueryState() { + + } + + public void setRankHistoryList(RankHistory rankHistoryList) { + this.rankHistoryList = rankHistoryList; + } + + public RankHistory getRankHistoryList() { + return rankHistoryList; + } +} diff --git a/src/main/java/interface_adapter/query/QueryViewModel.java b/src/main/java/interface_adapter/query/QueryViewModel.java new file mode 100644 index 000000000..54c56cff8 --- /dev/null +++ b/src/main/java/interface_adapter/query/QueryViewModel.java @@ -0,0 +1,20 @@ +package interface_adapter.query; + +import entity.RankHistory; +import interface_adapter.ViewModel; + +/** + * The View Model for the query view. + */ +public class QueryViewModel extends ViewModel { + + public QueryViewModel() { + super("query"); + setState(new QueryState()); + } + + public RankHistory getRankHistoryList() { + return getState().getRankHistoryList(); + } + +} From b8153d689a6b54aec8ffcb03a6c3f9bf00ded5a9 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Tue, 3 Dec 2024 10:48:56 -0500 Subject: [PATCH 113/125] Add Query view. --- src/main/java/view/QueryView.java | 64 +++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/main/java/view/QueryView.java diff --git a/src/main/java/view/QueryView.java b/src/main/java/view/QueryView.java new file mode 100644 index 000000000..0a9fb5b62 --- /dev/null +++ b/src/main/java/view/QueryView.java @@ -0,0 +1,64 @@ +package view; + +import entity.RankHistory; +import interface_adapter.ViewManagerModel; +import interface_adapter.query.QueryViewModel; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/** + * The view of user profile. + */ +public class QueryView extends JPanel implements ActionListener, PropertyChangeListener { + + private final String viewName = "query"; + private final QueryViewModel queryViewModel; + private final JPanel contentPanel; + + public QueryView(ViewManagerModel viewManagerModel, QueryViewModel queryViewModel) { + this.queryViewModel = queryViewModel; + this.queryViewModel.addPropertyChangeListener(this); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + final JLabel title = new JLabel("Rank History"); + title.setAlignmentX(Component.CENTER_ALIGNMENT); + + final JScrollPane scrollPane = new JScrollPane(); + + contentPanel = new JPanel(); + contentPanel.setLayout(new GridLayout(0, 1)); + + scrollPane.setViewportView(contentPanel); + + this.add(title); + this.add(scrollPane); + + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + final RankHistory rankHistory = queryViewModel.getRankHistoryList(); + for (int i = 0; i < rankHistory.getRanks().size(); i++) { + contentPanel.add(new JLabel(rankHistory.getRanks().get(i).toString())); + } + } + + /** + * React to a button click that results in evt. + * @param evt the ActionEvent to react to + */ + public void actionPerformed(ActionEvent evt) { + + } + + public String getViewName() { + return viewName; + } + +} From 3d70dbc78ff575415cd8da3912620ebd6915e753 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Tue, 3 Dec 2024 10:57:47 -0500 Subject: [PATCH 114/125] Add Query view in main class. --- src/main/java/app/MainChessAPP.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/app/MainChessAPP.java b/src/main/java/app/MainChessAPP.java index f338a9fd7..c118d3792 100644 --- a/src/main/java/app/MainChessAPP.java +++ b/src/main/java/app/MainChessAPP.java @@ -7,10 +7,12 @@ import javax.swing.WindowConstants; import data_access.ChessDataAccessObject; +import data_access.QueryDataAccessObject; import data_access.UserDataAccessObject; import interface_adapter.ViewManagerModel; import interface_adapter.logged_in.LoggedInViewModel; import interface_adapter.login.LoginViewModel; +import interface_adapter.query.QueryViewModel; import interface_adapter.showProfile.ShowProfileViewModel; import interface_adapter.signup.SignupViewModel; import view.*; @@ -40,8 +42,10 @@ public static void main(String[] args) { final LoggedInViewModel loggedInViewModel = new LoggedInViewModel(); final SignupViewModel signupViewModel = new SignupViewModel(); final ShowProfileViewModel showProfileViewModel = new ShowProfileViewModel(); + final QueryViewModel queryViewModel = new QueryViewModel(); final UserDataAccessObject userDataAccessObject = new UserDataAccessObject(); + final QueryDataAccessObject queryDataAccessObject = new QueryDataAccessObject(); final SignupView signupView = SignupUseCaseFactory.create(viewManagerModel, loginViewModel, signupViewModel, userDataAccessObject); @@ -50,11 +54,13 @@ public static void main(String[] args) { final LoggedInView loggedInView = ShowProfileUseCaseFactory.create(viewManagerModel, loggedInViewModel, signupViewModel, showProfileViewModel, userDataAccessObject); final ProfileView profileView = new ProfileView(viewManagerModel, showProfileViewModel); + final QueryView queryView = new QueryView(viewManagerModel, queryViewModel); views.add(signupView, signupView.getViewName()); views.add(loginView, loginView.getViewName()); views.add(loggedInView, loggedInView.getViewName()); views.add(profileView, profileView.getViewName()); + views.add(queryView, queryView.getViewName()); final ChessAppBuilder chessAppBuilder = new ChessAppBuilder(); chessAppBuilder.addChessDAO(new ChessDataAccessObject()) From e4f74910ec820c4651bb9a0a2036be8726093ade Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Tue, 3 Dec 2024 11:04:40 -0500 Subject: [PATCH 115/125] Update ShowProfileUseCaseFactory with query LoggedInView. --- .../java/app/ShowProfileUseCaseFactory.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/java/app/ShowProfileUseCaseFactory.java b/src/main/java/app/ShowProfileUseCaseFactory.java index 039b466ec..c4a00b8cb 100644 --- a/src/main/java/app/ShowProfileUseCaseFactory.java +++ b/src/main/java/app/ShowProfileUseCaseFactory.java @@ -4,10 +4,17 @@ import interface_adapter.logged_in.LoggedInController; import interface_adapter.logged_in.LoggedInPresenter; import interface_adapter.logged_in.LoggedInViewModel; +import interface_adapter.query.QueryController; +import interface_adapter.query.QueryPresenter; +import interface_adapter.query.QueryViewModel; import interface_adapter.showProfile.ShowProfileController; import interface_adapter.showProfile.ShowProfilePresenter; import interface_adapter.showProfile.ShowProfileViewModel; import interface_adapter.signup.SignupViewModel; +import use_case.query.QueryDataAccessInterface; +import use_case.query.QueryInputBoundary; +import use_case.query.QueryInteractor; +import use_case.query.QueryOutputBoundary; import use_case.logged_in.LoggedInInputBoundary; import use_case.logged_in.LoggedInInteractor; import use_case.logged_in.LoggedInOutputBoundary; @@ -35,6 +42,8 @@ private ShowProfileUseCaseFactory() { * @param signupViewModel the signupViewModel * @param showProfileViewModel the showProfileViewModel * @param userDataAccessObject the ChangePasswordUserDataAccessInterface to inject into the LoggedInView + * @param queryViewModel the QueryViewModel to inject into the LoggedInView + * @param queryDataAccessObject the Query DataAccessObject * @return the LoggedInView created for the provided input classes */ public static LoggedInView create( @@ -42,16 +51,23 @@ public static LoggedInView create( LoggedInViewModel loggedInViewModel, SignupViewModel signupViewModel, ShowProfileViewModel showProfileViewModel, - ShowProfileUserDataAccessInterface userDataAccessObject) { + QueryViewModel queryViewModel, + ShowProfileUserDataAccessInterface userDataAccessObject, + QueryDataAccessInterface queryDataAccessObject) { final ShowProfileController showProfileController = createShowProfileUseCase(viewManagerModel, loggedInViewModel, showProfileViewModel, userDataAccessObject); + final QueryOutputBoundary queryOutputBoundary = new QueryPresenter(queryViewModel, viewManagerModel); + final QueryInputBoundary queryInputInteractor = new QueryInteractor(queryDataAccessObject, queryOutputBoundary); + final QueryController queryController = new QueryController(queryInputInteractor); + final LoggedInController loggedInController = createLoggedInUseCase(viewManagerModel, loggedInViewModel, signupViewModel); - return new LoggedInView(viewManagerModel, loggedInController, loggedInViewModel, showProfileController); + return new LoggedInView(viewManagerModel, loggedInController, loggedInViewModel, + showProfileController, queryController); } private static ShowProfileController createShowProfileUseCase( From 37b5fa77fd77b3c5713f349ea6236c03b345e1e5 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Tue, 3 Dec 2024 11:10:02 -0500 Subject: [PATCH 116/125] Update LoggedInView to add JButton of showRankHistory. --- src/main/java/view/LoggedInView.java | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/main/java/view/LoggedInView.java b/src/main/java/view/LoggedInView.java index f0af5108a..7115b733d 100644 --- a/src/main/java/view/LoggedInView.java +++ b/src/main/java/view/LoggedInView.java @@ -14,6 +14,7 @@ import interface_adapter.logged_in.LoggedInController; import interface_adapter.logged_in.LoggedInState; import interface_adapter.logged_in.LoggedInViewModel; +import interface_adapter.query.QueryController; import interface_adapter.showProfile.ShowProfileController; /** @@ -32,11 +33,13 @@ public class LoggedInView extends JPanel implements ActionListener, PropertyChan private final JButton startChess; private final JButton showProfile; + private final JButton showRankHistory; private final ShowProfileController showProfileController; public LoggedInView(ViewManagerModel viewManagerModel, LoggedInController loggedInController, LoggedInViewModel loggedInViewModel, - ShowProfileController showProfileController) { + ShowProfileController showProfileController, + QueryController queryController) { this.loggedInController = loggedInController; this.loggedInViewModel = loggedInViewModel; this.showProfileController = showProfileController; @@ -55,6 +58,9 @@ public LoggedInView(ViewManagerModel viewManagerModel, LoggedInController logged showProfile = new JButton("Show Profile"); buttons.add(showProfile); + showRankHistory = new JButton("Show Rank History"); + buttons.add(showRankHistory); + startChess = new JButton("Start Chess Game"); buttons.add(startChess); @@ -91,6 +97,20 @@ public void actionPerformed(ActionEvent evt) { } ); + showRankHistory.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(showRankHistory)) { + final LoggedInState currentState = loggedInViewModel.getState(); + + queryController.execute( + currentState.getUsername() + ); + } + } + } + ); + this.add(title); this.add(usernameInfo); this.add(username); From b7e17bc893342a060e29d753bc8007a8424c627b Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Tue, 3 Dec 2024 11:16:07 -0500 Subject: [PATCH 117/125] Fix MainChessApp LoggedInView parameters queryViewModel and queryDAO. --- src/main/java/app/MainChessAPP.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/app/MainChessAPP.java b/src/main/java/app/MainChessAPP.java index c118d3792..7380f3fa9 100644 --- a/src/main/java/app/MainChessAPP.java +++ b/src/main/java/app/MainChessAPP.java @@ -52,7 +52,7 @@ public static void main(String[] args) { final LoginView loginView = LoginUseCaseFactory.create(viewManagerModel, loginViewModel, loggedInViewModel, userDataAccessObject, signupViewModel); final LoggedInView loggedInView = ShowProfileUseCaseFactory.create(viewManagerModel, loggedInViewModel, - signupViewModel, showProfileViewModel, userDataAccessObject); + signupViewModel, showProfileViewModel, queryViewModel, userDataAccessObject, queryDataAccessObject); final ProfileView profileView = new ProfileView(viewManagerModel, showProfileViewModel); final QueryView queryView = new QueryView(viewManagerModel, queryViewModel); From 57b858c4fbfd0b08d4271217a3b03bea79411ffd Mon Sep 17 00:00:00 2001 From: J0hnDing Date: Tue, 3 Dec 2024 12:39:47 -0500 Subject: [PATCH 118/125] README.md update --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d64638d00..5fc7763e9 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,12 @@ Note: New user's rank point is set to ```0``` ### Step by step move -// TODO +This feature enables users to move a chess piece to a valid position during their turn. +Since moving a piece involves two steps, select and move, this usecase have two functionality. +To Select: User clicks on the square containing the chess piece they want to select. The program then highlights all valid moves in yellow. +To Move: If one piece is selected and the user clicks on one of the highlighted squares, the chess piece is moved to the target position. + +Note: Clicking an invalid move after select deselects the piece. ## Usage Guide From e5a9e7367745b11af17a389afd3a531fb9e08b79 Mon Sep 17 00:00:00 2001 From: DMA <1670639177@qq.com> Date: Tue, 3 Dec 2024 12:43:32 -0500 Subject: [PATCH 119/125] add show profile gif for README.md --- Show Profilegif.gif | Bin 0 -> 33967 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Show Profilegif.gif diff --git a/Show Profilegif.gif b/Show Profilegif.gif new file mode 100644 index 0000000000000000000000000000000000000000..1484376dde7cce291678727179b648ce688c36a7 GIT binary patch literal 33967 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 literal 0 HcmV?d00001 From 0524890f82536e44912351743540b0a8ebfe1f85 Mon Sep 17 00:00:00 2001 From: DMA <1670639177@qq.com> Date: Tue, 3 Dec 2024 12:52:15 -0500 Subject: [PATCH 120/125] README.md update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0d81beae7..e58e09b7f 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ User can view their profile (Contain User name and rank point currently) after l Note: New user's rank point is set to ```0``` - +![Alt Text](https://github.com/DDMMMAA/CSC207-Team179/blob/main/Show%20Profilegif.gif?raw=true) ### Generate daily puzzle From a3349906e7e7fd57cd9e04fae4d4bc12d1728d31 Mon Sep 17 00:00:00 2001 From: DMA <1670639177@qq.com> Date: Tue, 3 Dec 2024 12:54:13 -0500 Subject: [PATCH 121/125] README.md update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e58e09b7f..700354f5f 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ User can view their profile (Contain User name and rank point currently) after l Note: New user's rank point is set to ```0``` -![Alt Text](https://github.com/DDMMMAA/CSC207-Team179/blob/main/Show%20Profilegif.gif?raw=true) +![Show Profile](https://github.com/DDMMMAA/CSC207-Team179/blob/main/Show%20Profilegif.gif?raw=true) ### Generate daily puzzle From dd6b13e3929a8d9a904fb3f67beec04e22cb4d57 Mon Sep 17 00:00:00 2001 From: J0hnDing Date: Tue, 3 Dec 2024 13:35:08 -0500 Subject: [PATCH 122/125] README.md update2 --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5fc7763e9..627d58dc1 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,9 @@ Note: New user's rank point is set to ```0``` This feature enables users to move a chess piece to a valid position during their turn. Since moving a piece involves two steps, select and move, this usecase have two functionality. -To Select: User clicks on the square containing the chess piece they want to select. The program then highlights all valid moves in yellow. + +To Select: User clicks on the square containing the chess piece they want to select. The program then highlights all valid moves in yellow. + To Move: If one piece is selected and the user clicks on one of the highlighted squares, the chess piece is moved to the target position. Note: Clicking an invalid move after select deselects the piece. From 5b4c0b4fa9c1108a7368055d8c715de782be2a32 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Tue, 3 Dec 2024 13:51:41 -0500 Subject: [PATCH 123/125] Update Query. --- src/Main.java | 5 + src/main/java/app/LoginUseCaseFactory.java | 1 + src/main/java/app/MainChessAPP.java | 79 ------------ src/main/java/app/MainChessApp.java | 21 +++ .../java/app/ShowProfileUseCaseFactory.java | 12 +- src/main/java/app/UserAppBuilder.java | 122 ++++++++++++++++++ .../interface_adapter/move/MovePresenter.java | 31 ++--- src/main/java/view/LoggedInView.java | 22 +--- src/main/java/view/LoginView.java | 2 - src/test/java/SignupANDLogin/LoginTest.java | 38 ++++++ src/test/java/SignupANDLogin/SignupTest.java | 38 ++++++ 11 files changed, 244 insertions(+), 127 deletions(-) create mode 100644 src/Main.java delete mode 100644 src/main/java/app/MainChessAPP.java create mode 100644 src/main/java/app/MainChessApp.java create mode 100644 src/main/java/app/UserAppBuilder.java create mode 100644 src/test/java/SignupANDLogin/LoginTest.java create mode 100644 src/test/java/SignupANDLogin/SignupTest.java diff --git a/src/Main.java b/src/Main.java new file mode 100644 index 000000000..3e59c38fb --- /dev/null +++ b/src/Main.java @@ -0,0 +1,5 @@ +public class Main { + public static void main(String[] args) { + System.out.println("Hello world!"); + } +} \ No newline at end of file diff --git a/src/main/java/app/LoginUseCaseFactory.java b/src/main/java/app/LoginUseCaseFactory.java index daa4ef2ac..d0d6fef26 100644 --- a/src/main/java/app/LoginUseCaseFactory.java +++ b/src/main/java/app/LoginUseCaseFactory.java @@ -28,6 +28,7 @@ private LoginUseCaseFactory() { * @param loginViewModel the LoginViewModel to inject into the LoginView * @param loggedInViewModel the LoggedInViewModel to inject into the LoginView * @param userDataAccessObject the LoginUserDataAccessInterface to inject into the LoginView + * @param signupViewModel the SignupViewModel to inject into the LoginView * @return the LoginView created for the provided input classes */ public static LoginView create( diff --git a/src/main/java/app/MainChessAPP.java b/src/main/java/app/MainChessAPP.java deleted file mode 100644 index 7380f3fa9..000000000 --- a/src/main/java/app/MainChessAPP.java +++ /dev/null @@ -1,79 +0,0 @@ -package app; - -import java.awt.CardLayout; - -import javax.swing.JFrame; -import javax.swing.JPanel; -import javax.swing.WindowConstants; - -import data_access.ChessDataAccessObject; -import data_access.QueryDataAccessObject; -import data_access.UserDataAccessObject; -import interface_adapter.ViewManagerModel; -import interface_adapter.logged_in.LoggedInViewModel; -import interface_adapter.login.LoginViewModel; -import interface_adapter.query.QueryViewModel; -import interface_adapter.showProfile.ShowProfileViewModel; -import interface_adapter.signup.SignupViewModel; -import view.*; - -/** - * Main that activates login page. - */ -public class MainChessAPP { - - /** - * The main method for starting the program with an external database used to persist user data. - * @param args input to main - */ - public static void main(String[] args) { - - final JFrame frame = new JFrame("Chess Game Login"); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - - final CardLayout cardLayout = new CardLayout(); - final JPanel views = new JPanel(cardLayout); - frame.add(views); - - final ViewManagerModel viewManagerModel = new ViewManagerModel(); - new ViewManager(views, cardLayout, viewManagerModel); - - final LoginViewModel loginViewModel = new LoginViewModel(); - final LoggedInViewModel loggedInViewModel = new LoggedInViewModel(); - final SignupViewModel signupViewModel = new SignupViewModel(); - final ShowProfileViewModel showProfileViewModel = new ShowProfileViewModel(); - final QueryViewModel queryViewModel = new QueryViewModel(); - - final UserDataAccessObject userDataAccessObject = new UserDataAccessObject(); - final QueryDataAccessObject queryDataAccessObject = new QueryDataAccessObject(); - - final SignupView signupView = SignupUseCaseFactory.create(viewManagerModel, loginViewModel, - signupViewModel, userDataAccessObject); - final LoginView loginView = LoginUseCaseFactory.create(viewManagerModel, loginViewModel, - loggedInViewModel, userDataAccessObject, signupViewModel); - final LoggedInView loggedInView = ShowProfileUseCaseFactory.create(viewManagerModel, loggedInViewModel, - signupViewModel, showProfileViewModel, queryViewModel, userDataAccessObject, queryDataAccessObject); - final ProfileView profileView = new ProfileView(viewManagerModel, showProfileViewModel); - final QueryView queryView = new QueryView(viewManagerModel, queryViewModel); - - views.add(signupView, signupView.getViewName()); - views.add(loginView, loginView.getViewName()); - views.add(loggedInView, loggedInView.getViewName()); - views.add(profileView, profileView.getViewName()); - views.add(queryView, queryView.getViewName()); - - final ChessAppBuilder chessAppBuilder = new ChessAppBuilder(); - chessAppBuilder.addChessDAO(new ChessDataAccessObject()) - .addMoveView() - .addMoveUseCase(); - - final ChessBoardView chessBoardView = chessAppBuilder.buildChessBoardView(); - views.add(chessBoardView, "chessBoardView"); - - viewManagerModel.setState(signupView.getViewName()); - viewManagerModel.firePropertyChanged(); - - frame.pack(); - frame.setVisible(true); - } -} diff --git a/src/main/java/app/MainChessApp.java b/src/main/java/app/MainChessApp.java new file mode 100644 index 000000000..12e1010be --- /dev/null +++ b/src/main/java/app/MainChessApp.java @@ -0,0 +1,21 @@ +package app; + +/** + * Main that activates login page. + */ +public class MainChessApp { + + /** + * The main method for starting the program with an external database used to persist user data. + * @param args input to main + */ + public static void main(String[] args) { + + final UserAppBuilder userAppBuilder = new UserAppBuilder(); + userAppBuilder.addViewModels() + .addViews() + .initializeState() + .addChessGame() + .build(); + } +} diff --git a/src/main/java/app/ShowProfileUseCaseFactory.java b/src/main/java/app/ShowProfileUseCaseFactory.java index c4a00b8cb..7d2d48b65 100644 --- a/src/main/java/app/ShowProfileUseCaseFactory.java +++ b/src/main/java/app/ShowProfileUseCaseFactory.java @@ -11,13 +11,13 @@ import interface_adapter.showProfile.ShowProfilePresenter; import interface_adapter.showProfile.ShowProfileViewModel; import interface_adapter.signup.SignupViewModel; +import use_case.logged_in.LoggedInInputBoundary; +import use_case.logged_in.LoggedInInteractor; +import use_case.logged_in.LoggedInOutputBoundary; import use_case.query.QueryDataAccessInterface; import use_case.query.QueryInputBoundary; import use_case.query.QueryInteractor; import use_case.query.QueryOutputBoundary; -import use_case.logged_in.LoggedInInputBoundary; -import use_case.logged_in.LoggedInInteractor; -import use_case.logged_in.LoggedInOutputBoundary; import use_case.showProfile.ShowProfileInputBoundary; import use_case.showProfile.ShowProfileInteractor; import use_case.showProfile.ShowProfileOutputBoundary; @@ -56,7 +56,7 @@ public static LoggedInView create( QueryDataAccessInterface queryDataAccessObject) { final ShowProfileController showProfileController = - createShowProfileUseCase(viewManagerModel, loggedInViewModel, + createShowProfileUseCase(viewManagerModel, showProfileViewModel, userDataAccessObject); final QueryOutputBoundary queryOutputBoundary = new QueryPresenter(queryViewModel, viewManagerModel); @@ -66,13 +66,11 @@ public static LoggedInView create( final LoggedInController loggedInController = createLoggedInUseCase(viewManagerModel, loggedInViewModel, signupViewModel); - return new LoggedInView(viewManagerModel, loggedInController, loggedInViewModel, - showProfileController, queryController); + return new LoggedInView(viewManagerModel, loggedInController, loggedInViewModel, showProfileController); } private static ShowProfileController createShowProfileUseCase( ViewManagerModel viewManagerModel, - LoggedInViewModel loggedInViewModel, ShowProfileViewModel showProfileViewModel, ShowProfileUserDataAccessInterface userDataAccessObject) { diff --git a/src/main/java/app/UserAppBuilder.java b/src/main/java/app/UserAppBuilder.java new file mode 100644 index 000000000..b50a756e0 --- /dev/null +++ b/src/main/java/app/UserAppBuilder.java @@ -0,0 +1,122 @@ +package app; + +import java.awt.CardLayout; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.WindowConstants; + +import data_access.ChessDataAccessObject; +import data_access.QueryDataAccessObject; +import data_access.UserDataAccessObject; +import interface_adapter.ViewManagerModel; +import interface_adapter.logged_in.LoggedInViewModel; +import interface_adapter.login.LoginViewModel; +import interface_adapter.query.QueryViewModel; +import interface_adapter.showProfile.ShowProfileViewModel; +import interface_adapter.signup.SignupViewModel; +import view.ChessBoardView; +import view.LoggedInView; +import view.LoginView; +import view.ProfileView; +import view.QueryView; +import view.SignupView; +import view.ViewManager; + +public class UserAppBuilder { + private CardLayout cardLayout; + private JPanel views; + private ViewManagerModel viewManagerModel; + private ChessBoardView chessBoardView; + private UserDataAccessObject userDataAccessObject; + private QueryDataAccessObject queryDataAccessObject; + + private LoginViewModel loginViewModel; + private LoggedInViewModel loggedInViewModel; + private SignupViewModel signupViewModel; + private ShowProfileViewModel showProfileViewModel; + private QueryViewModel queryViewModel; + + public UserAppBuilder() { + this.cardLayout = new CardLayout(); + this.views = new JPanel(cardLayout); + this.viewManagerModel = new ViewManagerModel(); + this.userDataAccessObject = new UserDataAccessObject(); + this.queryDataAccessObject = new QueryDataAccessObject(); + new ViewManager(views, cardLayout, viewManagerModel); + } + + /** + * Set the addViewModels to be used in this application. + * @return this builder + */ + public UserAppBuilder addViewModels() { + this.loginViewModel = new LoginViewModel(); + this.loggedInViewModel = new LoggedInViewModel(); + this.signupViewModel = new SignupViewModel(); + this.showProfileViewModel = new ShowProfileViewModel(); + this.queryViewModel = new QueryViewModel(); + return this; + } + + /** + * Set the addViews to be used in this application. + * @return this builder + */ + public UserAppBuilder addViews() { + final SignupView signupView = SignupUseCaseFactory.create(viewManagerModel, loginViewModel, signupViewModel, + userDataAccessObject); + final LoginView loginView = LoginUseCaseFactory.create(viewManagerModel, loginViewModel, loggedInViewModel, + userDataAccessObject, signupViewModel); + final LoggedInView loggedInView = ShowProfileUseCaseFactory.create(viewManagerModel, loggedInViewModel, + signupViewModel, showProfileViewModel, queryViewModel, userDataAccessObject, queryDataAccessObject); + final ProfileView profileView = new ProfileView(viewManagerModel, showProfileViewModel); + final QueryView queryView = new QueryView(viewManagerModel, queryViewModel); + + views.add(signupView, signupView.getViewName()); + views.add(loginView, loginView.getViewName()); + views.add(loggedInView, loggedInView.getViewName()); + views.add(profileView, profileView.getViewName()); + views.add(queryView, queryView.getViewName()); + + return this; + } + + /** + * Set the addChessGame to be used in this application. + * @return this builder + */ + public UserAppBuilder addChessGame() { + final ChessAppBuilder chessAppBuilder = new ChessAppBuilder(); + chessAppBuilder.addChessDAO(new ChessDataAccessObject()) + .addMoveView() + .addMoveUseCase(); + + this.chessBoardView = chessAppBuilder.buildChessBoardView(); + this.views.add(chessBoardView, "chessBoardView"); + return this; + } + + /** + * Set the initializeState to be used in this application. + * @return this builder + */ + public UserAppBuilder initializeState() { + this.viewManagerModel.setState("signUpView"); + this.viewManagerModel.firePropertyChanged(); + return this; + } + + /** + * Set the build to be used in this application. + * @return this builder + */ + public JFrame build() { + final JFrame frame = new JFrame("Chess Game Login"); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.add(this.views); + frame.pack(); + frame.setVisible(true); + return frame; + } +} diff --git a/src/main/java/interface_adapter/move/MovePresenter.java b/src/main/java/interface_adapter/move/MovePresenter.java index 29a02e976..f163ef262 100644 --- a/src/main/java/interface_adapter/move/MovePresenter.java +++ b/src/main/java/interface_adapter/move/MovePresenter.java @@ -1,14 +1,10 @@ package interface_adapter.move; -//import chariot.model.MoveInfo; -//import chariot.util.Board; import interface_adapter.ViewManagerModel; -import use_case.move.MoveInputdata; +import java.util.ArrayList; import use_case.move.MoveOutputBoundary; import use_case.move.MoveOutputdata; -import java.util.ArrayList; - /** * The presenter for Move use case. */ @@ -21,54 +17,53 @@ public MovePresenter(MoveViewModel moveViewModel, ViewManagerModel viewManagerMo this.viewManagerModel = viewManagerModel; } - public void prepareMove(MoveOutputdata input) { String[][] pieces = new String[8][8]; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { if (input.getBoard().isEmpty(new int[] {i, j})) { - pieces[7-i][j] = null; + pieces[7 - i][j] = null; } else { if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.Bishop) { if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { - pieces[7-i][j] = "♗"; + pieces[7 - i][j] = "♗"; } else { - pieces[7-i][j] = "♝"; + pieces[7 - i][j] = "♝"; } } else if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.Rook) { if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { - pieces[7-i][j] = "♖"; + pieces[7 - i][j] = "♖"; } else { - pieces[7-i][j] = "♜"; + pieces[7 - i][j] = "♜"; } } else if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.Knight) { if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { - pieces[7-i][j] = "♘"; + pieces[7 - i][j] = "♘"; } else { - pieces[7-i][j] = "♞"; + pieces[7 - i][j] = "♞"; } } else if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.Pawn) { if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { - pieces[7-i][j] = "♙"; + pieces[7 - i][j] = "♙"; } else { - pieces[7-i][j] = "♟"; + pieces[7 - i][j] = "♟"; } } else if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.Queen) { if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { - pieces[7-i][j]= "♕"; + pieces[7 - i][j] = "♕"; } else { pieces[7-i][j]= "♛"; } } else if (input.getBoard().getPiece(new int[] {i, j}) instanceof entity.King) { if (input.getBoard().getPiece(new int[] {i, j}).getColor().equals("White")) { - pieces[7-i][j] = "♔"; + pieces[7 - i][j] = "♔"; } else { - pieces[7-i][j] = "♚"; + pieces[7 - i][j] = "♚"; } } } diff --git a/src/main/java/view/LoggedInView.java b/src/main/java/view/LoggedInView.java index 7115b733d..f0af5108a 100644 --- a/src/main/java/view/LoggedInView.java +++ b/src/main/java/view/LoggedInView.java @@ -14,7 +14,6 @@ import interface_adapter.logged_in.LoggedInController; import interface_adapter.logged_in.LoggedInState; import interface_adapter.logged_in.LoggedInViewModel; -import interface_adapter.query.QueryController; import interface_adapter.showProfile.ShowProfileController; /** @@ -33,13 +32,11 @@ public class LoggedInView extends JPanel implements ActionListener, PropertyChan private final JButton startChess; private final JButton showProfile; - private final JButton showRankHistory; private final ShowProfileController showProfileController; public LoggedInView(ViewManagerModel viewManagerModel, LoggedInController loggedInController, LoggedInViewModel loggedInViewModel, - ShowProfileController showProfileController, - QueryController queryController) { + ShowProfileController showProfileController) { this.loggedInController = loggedInController; this.loggedInViewModel = loggedInViewModel; this.showProfileController = showProfileController; @@ -58,9 +55,6 @@ public LoggedInView(ViewManagerModel viewManagerModel, LoggedInController logged showProfile = new JButton("Show Profile"); buttons.add(showProfile); - showRankHistory = new JButton("Show Rank History"); - buttons.add(showRankHistory); - startChess = new JButton("Start Chess Game"); buttons.add(startChess); @@ -97,20 +91,6 @@ public void actionPerformed(ActionEvent evt) { } ); - showRankHistory.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent evt) { - if (evt.getSource().equals(showRankHistory)) { - final LoggedInState currentState = loggedInViewModel.getState(); - - queryController.execute( - currentState.getUsername() - ); - } - } - } - ); - this.add(title); this.add(usernameInfo); this.add(username); diff --git a/src/main/java/view/LoginView.java b/src/main/java/view/LoginView.java index 473fb9084..8b0f0bf6f 100644 --- a/src/main/java/view/LoginView.java +++ b/src/main/java/view/LoginView.java @@ -72,8 +72,6 @@ public void actionPerformed(ActionEvent evt) { } ); - //cancel.addActionListener(this); - cancel.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { diff --git a/src/test/java/SignupANDLogin/LoginTest.java b/src/test/java/SignupANDLogin/LoginTest.java new file mode 100644 index 000000000..55564831b --- /dev/null +++ b/src/test/java/SignupANDLogin/LoginTest.java @@ -0,0 +1,38 @@ +package SignupANDLogin; + +import data_access.UserDataAccessObject; +import entity.User; +import org.junit.Test; +import use_case.login.*; + +import static org.junit.Assert.*; + +public class LoginTest { + + @Test + public void successTest() { + LoginInputData inputData = new LoginInputData("uno", "uno"); + LoginUserDataAccessInterface userRepository = new UserDataAccessObject(); + + User user = new User("uno", "uno"); + userRepository.save(user); + + LoginOutputBoundary successPresenter = new LoginOutputBoundary() { + @Override + public void prepareSuccessView(LoginOutputData user) { + assertEquals("uno", user.getUsername()); + } + + @Override + public void prepareFailView(String error) { + fail("Use case failure is unexpected."); + } + + @Override + public void switchToSignUpView(){} + }; + + LoginInputBoundary interactor = new LoginInteractor(userRepository, successPresenter); + interactor.execute(inputData); + } +} \ No newline at end of file diff --git a/src/test/java/SignupANDLogin/SignupTest.java b/src/test/java/SignupANDLogin/SignupTest.java new file mode 100644 index 000000000..04c776e53 --- /dev/null +++ b/src/test/java/SignupANDLogin/SignupTest.java @@ -0,0 +1,38 @@ +package SignupANDLogin; + +import org.junit.Test; +import use_case.signup.*; +import data_access.UserDataAccessObject; + +import static org.junit.Assert.*; + +public class SignupTest { + + @Test + public void successTest() { + SignupInputData inputData = new SignupInputData("uno", "uno", "uno"); + SignupUserDataAccessInterface userRepository = new UserDataAccessObject(); + + SignupOutputBoundary successPresenter = new SignupOutputBoundary() { + @Override + public void prepareSuccessView(SignupOutputData user) { + // 2 things to check: the output data is correct, and the user has been created in the DAO. + assertEquals("uno", user.getUsername()); + assertTrue(userRepository.existsByName("uno")); + } + + @Override + public void prepareFailView(String error) { + fail("Use case failure is unexpected."); + } + + @Override + public void switchToLoginView() { + // This is expected + } + }; + + SignupInputBoundary interactor = new SignupInteractor(userRepository, successPresenter); + interactor.execute(inputData); + } +} From 654798f3dbde240c0eb5fe7f4af2a9b840b3ac85 Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Tue, 3 Dec 2024 14:25:08 -0500 Subject: [PATCH 124/125] Update Query. --- .../java/app/ShowProfileUseCaseFactory.java | 3 ++- src/main/java/view/LoggedInView.java | 24 ++++++++++++++++++- src/main/java/view/ProfileView.java | 2 ++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/main/java/app/ShowProfileUseCaseFactory.java b/src/main/java/app/ShowProfileUseCaseFactory.java index 7d2d48b65..6ef95e9aa 100644 --- a/src/main/java/app/ShowProfileUseCaseFactory.java +++ b/src/main/java/app/ShowProfileUseCaseFactory.java @@ -66,7 +66,8 @@ public static LoggedInView create( final LoggedInController loggedInController = createLoggedInUseCase(viewManagerModel, loggedInViewModel, signupViewModel); - return new LoggedInView(viewManagerModel, loggedInController, loggedInViewModel, showProfileController); + return new LoggedInView(viewManagerModel, loggedInController, loggedInViewModel, + showProfileController, queryController); } private static ShowProfileController createShowProfileUseCase( diff --git a/src/main/java/view/LoggedInView.java b/src/main/java/view/LoggedInView.java index f0af5108a..6375250d1 100644 --- a/src/main/java/view/LoggedInView.java +++ b/src/main/java/view/LoggedInView.java @@ -14,6 +14,7 @@ import interface_adapter.logged_in.LoggedInController; import interface_adapter.logged_in.LoggedInState; import interface_adapter.logged_in.LoggedInViewModel; +import interface_adapter.query.QueryController; import interface_adapter.showProfile.ShowProfileController; /** @@ -32,14 +33,18 @@ public class LoggedInView extends JPanel implements ActionListener, PropertyChan private final JButton startChess; private final JButton showProfile; + private final JButton showRankHistory; private final ShowProfileController showProfileController; + private final QueryController queryController; public LoggedInView(ViewManagerModel viewManagerModel, LoggedInController loggedInController, LoggedInViewModel loggedInViewModel, - ShowProfileController showProfileController) { + ShowProfileController showProfileController, + QueryController queryController) { this.loggedInController = loggedInController; this.loggedInViewModel = loggedInViewModel; this.showProfileController = showProfileController; + this.queryController = queryController; this.loggedInViewModel.addPropertyChangeListener(this); final JLabel title = new JLabel("Logged In Screen"); @@ -55,6 +60,9 @@ public LoggedInView(ViewManagerModel viewManagerModel, LoggedInController logged showProfile = new JButton("Show Profile"); buttons.add(showProfile); + showRankHistory = new JButton("Show Rank History"); + buttons.add(showRankHistory); + startChess = new JButton("Start Chess Game"); buttons.add(startChess); @@ -91,6 +99,20 @@ public void actionPerformed(ActionEvent evt) { } ); + showRankHistory.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (evt.getSource().equals(showRankHistory)) { + final LoggedInState currentState = loggedInViewModel.getState(); + + queryController.execute( + currentState.getUsername() + ); + } + } + } + ); + this.add(title); this.add(usernameInfo); this.add(username); diff --git a/src/main/java/view/ProfileView.java b/src/main/java/view/ProfileView.java index e716ca3fa..40b7916ff 100644 --- a/src/main/java/view/ProfileView.java +++ b/src/main/java/view/ProfileView.java @@ -5,6 +5,8 @@ import interface_adapter.showProfile.ShowProfileState; import interface_adapter.showProfile.ShowProfileViewModel; + + import javax.swing.*; import javax.swing.text.View; import java.awt.*; From 03b1d185f0e4f25c4e5d712e4986f9a5d2efc99a Mon Sep 17 00:00:00 2001 From: YannChi22 Date: Tue, 3 Dec 2024 14:58:09 -0500 Subject: [PATCH 125/125] Delete src/Main.java --- src/Main.java | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 src/Main.java diff --git a/src/Main.java b/src/Main.java deleted file mode 100644 index 3e59c38fb..000000000 --- a/src/Main.java +++ /dev/null @@ -1,5 +0,0 @@ -public class Main { - public static void main(String[] args) { - System.out.println("Hello world!"); - } -} \ No newline at end of file