first commit

This commit is contained in:
lzh
2024-05-11 23:36:37 +08:00
commit 0d0e19670d
28 changed files with 1803 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/*
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 437 KiB

+162
View File
@@ -0,0 +1,162 @@
@startuml
class org.example.NumberleCLI {
- {static} String ANSI_RESET
- {static} String ANSI_GREEN
- {static} String ANSI_YELLOW
- {static} String ANSI_GRAY
- {static} INumberleModel model
- {static} Scanner scanner
+ {static} void main(String[])
- {static} boolean validateExpression(String)
- {static} void playGame()
- {static} void printCategories()
- {static} String getInput()
- {static} void printGameStatus()
- {static} void printColoredInput(String,String)
}
class org.example.NumberleModel {
- String TargetWord
+ ArrayList<String> NumberList
+ int remainAttempts
+ boolean gamewon
+ boolean Flag1
+ boolean Flag2
+ boolean Flag3
+ String DefaultNumberal
- StringBuilder CurrentGuess
+ void initialize()
+ boolean ProcessInput(String)
+ void remove()
+ void LoadList()
+ boolean processInput(String)
+ boolean isGameOver()
+ boolean isGameWon()
+ void setFlag(boolean)
+ void setFlag3(boolean)
+ void setTargetword(String)
+ String getTargetWord()
+ StringBuilder getCurrentGuess()
+ int getRemainingAttempts()
+ void setRemainingAttempts(int)
+ boolean startNewGame()
+ String DefaultWord()
}
class org.example.Main {
+ {static} void main(String[])
+ {static} void createAndShowGUI()
}
class org.example.NumberleController {
- NumberleView view
- INumberleModel model
+ int getRemainingAttempts()
+ void startNewGame()
+ void SetFlag(Boolean)
+ void setflag1(Boolean)
+ void setFlag2(Boolean)
+ void setView(NumberleView)
+ String getTargetWord()
+ void setRemainingAttempts(int)
+ void processInput(String)
+ boolean isGameOver()
+ boolean isGameWon()
+ void setTargetWord()
}
interface org.example.INumberleModel {
~ {static} int MAX_ATTEMPTS
~ void initialize()
~ boolean processInput(String)
~ boolean isGameOver()
~ boolean isGameWon()
~ void setFlag3(boolean)
~ void setFlag(boolean)
~ void setTargetword(String)
~ String getTargetWord()
~ StringBuilder getCurrentGuess()
~ int getRemainingAttempts()
~ void setRemainingAttempts(int)
~ boolean startNewGame()
~ String DefaultWord()
~ void remove()
}
class org.example.Junit {
- NumberleModel model
+ void Setup()
+ void TestNumber()
+ void testProcessInput()
+ void testRemove_EmptyGuess()
+ void testStartNewGame()
+ void testRemainingAttempts()
+ void testProcessInput_InvalidEquation()
+ void testProcessInput_InvalidInput()
}
class org.example.NumberleView {
- JPanel panel
- JLayeredPane layeredPane
- NumberleController controller
- INumberleModel model
+ JButton[][] button
- JTextField inputTextField
- int currentRow
- int CurrentCols
+ {static} int ROWS
+ {static} int COLS
+ {static} int MAX_INPUT_LENGTH
- {static} Color CORRECT_COLOR
- {static} Color INCORRECT_COLOR
- Color defaultColor
- JPanel row1
- JPanel row2
- boolean isDarkTheme
+ void initialize()
+ void Fixed()
+ void Swap()
+ void display()
+ void change()
+ void Input()
+ void Setting()
- void updateButtonsFromTarget(char[],String)
- void updateButtonsFromInput(String)
+ void Enter()
- boolean validateEquation(String)
+ void clearDisplay()
+ void updateDisplay(String)
+ void TooShort()
+ void MultiplyOperator()
+ void Symobol()
+ void HowtoPlayGame()
+ void NotEqual()
- void showGameStartReminder()
+ void NoEqualSign()
+ void Youlost()
+ void Youwon()
+ void update(Observable,Object)
}
class org.example.NumberleView$ButtonClickListener {
+ void actionPerformed(ActionEvent)
}
NumberleController->INumberleModel
NumberleView ->NumberleController
NumberleView ->INumberleModel
NumberleModel->NumberleCLI
org.example.INumberleModel <|.. org.example.NumberleModel
org.example.Observable <|-- org.example.NumberleModel
java.util.Observer <|.. org.example.NumberleView
org.example.JFrame <|-- org.example.NumberleView
org.example.NumberleView +.. org.example.NumberleView$ButtonClickListener
org.example.ActionListener <|.. org.example.NumberleView$ButtonClickListener
@enduml
+38
View File
@@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store
+8
View File
@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>
+14
View File
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_19" default="true" project-jdk-name="19" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
+162
View File
@@ -0,0 +1,162 @@
@startuml
class org.example.NumberleCLI {
- {static} String ANSI_RESET
- {static} String ANSI_GREEN
- {static} String ANSI_YELLOW
- {static} String ANSI_GRAY
- {static} INumberleModel model
- {static} Scanner scanner
+ {static} void main(String[])
- {static} boolean validateExpression(String)
- {static} void playGame()
- {static} void printCategories()
- {static} String getInput()
- {static} void printGameStatus()
- {static} void printColoredInput(String,String)
}
class org.example.NumberleModel {
- String TargetWord
+ ArrayList<String> NumberList
+ int remainAttempts
+ boolean gamewon
+ boolean Flag1
+ boolean Flag2
+ boolean Flag3
+ String DefaultNumberal
- StringBuilder CurrentGuess
+ void initialize()
+ boolean ProcessInput(String)
+ void remove()
+ void LoadList()
+ boolean processInput(String)
+ boolean isGameOver()
+ boolean isGameWon()
+ void setFlag(boolean)
+ void setFlag3(boolean)
+ void setTargetword(String)
+ String getTargetWord()
+ StringBuilder getCurrentGuess()
+ int getRemainingAttempts()
+ void setRemainingAttempts(int)
+ boolean startNewGame()
+ String DefaultWord()
}
class org.example.Main {
+ {static} void main(String[])
+ {static} void createAndShowGUI()
}
class org.example.NumberleController {
- NumberleView view
- INumberleModel model
+ int getRemainingAttempts()
+ void startNewGame()
+ void SetFlag(Boolean)
+ void setflag1(Boolean)
+ void setFlag2(Boolean)
+ void setView(NumberleView)
+ String getTargetWord()
+ void setRemainingAttempts(int)
+ void processInput(String)
+ boolean isGameOver()
+ boolean isGameWon()
+ void setTargetWord()
}
interface org.example.INumberleModel {
~ {static} int MAX_ATTEMPTS
~ void initialize()
~ boolean processInput(String)
~ boolean isGameOver()
~ boolean isGameWon()
~ void setFlag3(boolean)
~ void setFlag(boolean)
~ void setTargetword(String)
~ String getTargetWord()
~ StringBuilder getCurrentGuess()
~ int getRemainingAttempts()
~ void setRemainingAttempts(int)
~ boolean startNewGame()
~ String DefaultWord()
~ void remove()
}
class org.example.Junit {
- NumberleModel model
+ void Setup()
+ void TestNumber()
+ void testProcessInput()
+ void testRemove_EmptyGuess()
+ void testStartNewGame()
+ void testRemainingAttempts()
+ void testProcessInput_InvalidEquation()
+ void testProcessInput_InvalidInput()
}
class org.example.NumberleView {
- JPanel panel
- JLayeredPane layeredPane
- NumberleController controller
- INumberleModel model
+ JButton[][] button
- JTextField inputTextField
- int currentRow
- int CurrentCols
+ {static} int ROWS
+ {static} int COLS
+ {static} int MAX_INPUT_LENGTH
- {static} Color CORRECT_COLOR
- {static} Color INCORRECT_COLOR
- Color defaultColor
- JPanel row1
- JPanel row2
- boolean isDarkTheme
+ void initialize()
+ void Fixed()
+ void Swap()
+ void display()
+ void change()
+ void Input()
+ void Setting()
- void updateButtonsFromTarget(char[],String)
- void updateButtonsFromInput(String)
+ void Enter()
- boolean validateEquation(String)
+ void clearDisplay()
+ void updateDisplay(String)
+ void TooShort()
+ void MultiplyOperator()
+ void Symobol()
+ void HowtoPlayGame()
+ void NotEqual()
- void showGameStartReminder()
+ void NoEqualSign()
+ void Youlost()
+ void Youwon()
+ void update(Observable,Object)
}
class org.example.NumberleView$ButtonClickListener {
+ void actionPerformed(ActionEvent)
}
NumberleController->INumberleModel
NumberleView ->NumberleController
NumberleView ->INumberleModel
NumberleModel->NumberleCLI
org.example.INumberleModel <|.. org.example.NumberleModel
org.example.Observable <|-- org.example.NumberleModel
java.util.Observer <|.. org.example.NumberleView
org.example.JFrame <|-- org.example.NumberleView
org.example.NumberleView +.. org.example.NumberleView$ButtonClickListener
org.example.ActionListener <|.. org.example.NumberleView$ButtonClickListener
@enduml
+37
View File
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>wo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>19</maven.compiler.source>
<maven.compiler.target>19</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>net.objecthunter</groupId>
<artifactId>exp4j</artifactId>
<version>0.4.8</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

BIN
View File
Binary file not shown.
+37
View File
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>wo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>net.objecthunter</groupId>
<artifactId>exp4j</artifactId>
<version>0.4.8</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,29 @@
package org.example;
public interface INumberleModel{
int Attempt = 6;
void StartGame();
boolean processInput(String input);
boolean isGameOver();
boolean isGameWon();
void setFlag3(boolean flag3);
boolean input(String input);
void setFlag(boolean flag1);
void setTargetword(String targetword);
String getTargetWord();
StringBuilder getCurrentGuess();
int getRemainingAttempts();
void setRemainingAttempts(int val);
boolean startNewGame();
void Delete();
}
+63
View File
@@ -0,0 +1,63 @@
package org.example;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
import org.junit.Before;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import static org.junit.Assert.*;
public class Junit {
private NumberleModel model;
private NumberleView view;
@Before
public void Setup(){
model=new NumberleModel();
}
@Test
public void TestNumber(){
model.setTargetword("2*4=4*2");
model.input("2*4=4*2");
assertEquals("2*4=4*2",model.getTargetWord());
assertTrue(model.Gamewon);
}
@Test
public void ProcessInput(){
model.StartGame();
assertFalse(model.processInput(""));
assertFalse(model.processInput("3*2=2*8"));
assertFalse(model.isGameWon());
}
@Test
public void Remove_EmptyGuess() {
model.StartGame();
assertEquals(0, model.getCurrentGuess().length());
}
@Test
public void StartNewGame() {
model.StartGame();
String oldTargetWord = model.getTargetWord();
model.startNewGame();
assertNotEquals(oldTargetWord, model.getTargetWord());
}
@Test
public void testProcessInput_InvalidEquation() {
model.setFlag3(true);
model.StartGame();
assertFalse(model.processInput("1+2=2+3"));
assertFalse(model.isGameWon());
}
}
+11
View File
@@ -0,0 +1,11 @@
package org.example;
public class Main {
public static void main(String[] args) {
INumberleModel model = new NumberleModel();
NumberleController controller=new NumberleController(model);
NumberleView view = new NumberleView(model, controller);
}
}
+118
View File
@@ -0,0 +1,118 @@
package org.example;
import java.util.Scanner;
import net.objecthunter.exp4j.Expression;
import net.objecthunter.exp4j.ExpressionBuilder;
public class NumberleCLI {
private static final String GREEN = "\u001B[32m";
private static final String YELLOW = "\u001B[33m";
private static final String White = "\u001B[36m";
private static final String GRAY = "\u001B[90m";
private static final INumberleModel model = new NumberleModel();
private static final Scanner scanner = new Scanner(System.in);
private static void GameStart() {
while (!model.isGameOver()) {
GameStatue();
String input = InputInformation();
if (input.length()<7){
System.out.println("the input length is too short ");
}
boolean containsOperator = false; // Flag to check if an operator is present
for (char c : input.toCharArray()) {
if ("+-*/".indexOf(c) != -1) {
containsOperator = true; // Set flag if an operator is found
break;
}
}
boolean equal=input.contains("=");
boolean containsMultiple=input.contains("+-*/");
boolean containMultiples=input.contains("+-/");
if (!equal){
System.out.println("no equal please try again ");
} else if (containMultiples||containsMultiple) {
System.out.println("the Multiple operator");
}else if (!containsOperator){
System.out.println("at least one operator");
}
if (input.length()==7) {
if (correct(input)){
boolean correct = model.input(input);
ColoredInput(input, model.getTargetWord());
if (correct) {
break;
}
}
}
}
if (model.isGameWon()) {
System.out.println("wow! you won the game ");
} else {
System.out.println("Game over ! your lose the game !");
System.out.println("The right answer is " + model.getTargetWord());
}
}
private static void printCategories() {
System.out.println("operator: + - * / =");
System.out.println("number: 0 1 2 3 4 5 6 7 8 9");
}
private static String InputInformation() {
System.out.print("please enter your guess: ");
return scanner.nextLine();
}
private static void GameStatue() {
System.out.println("the target equation: " + model.getTargetWord());
System.out.println("you have : " + model.getRemainingAttempts()+" "+"chances");
System.out.println("your input guess is : " + model.getCurrentGuess());
printCategories();
}
private static void ColoredInput(String input, String target) {
StringBuilder SE = new StringBuilder();
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (i < target.length() && c == target.charAt(i)) {
SE.append(GREEN).append(c);
} else if (target.contains(String.valueOf(c))) {
SE.append(YELLOW).append(c);
} else {
SE.append(GRAY).append(c);
}
}
SE.append(White);
System.out.println(SE.toString());
}
private static boolean correct(String input) {
String[] EQUAL = input.split("=");
if (EQUAL.length != 2) {
return false;
}
Expression expLeft = new ExpressionBuilder(EQUAL[0].trim()).build();
double leftResult = expLeft.evaluate();
Expression expRight = new ExpressionBuilder(EQUAL[1].trim()).build();
double rightResult = expRight.evaluate();
if (leftResult!=rightResult){
System.out.println("the left side is not equal right side ");
}
return Double.compare(leftResult, rightResult) == 0;
}
public static void main(String[] args) {
model.startNewGame();
GameStart();
}
}
@@ -0,0 +1,61 @@
package org.example;
public class NumberleController {
private NumberleView view;
private INumberleModel model;
public NumberleController(INumberleModel model) {
this.model = model;
}
public int getRemainingAttempts() {
return model.getRemainingAttempts();
}
public void startNewGame() {
model.startNewGame();
}
public void SetFlag(Boolean Flag3){
model.setFlag3(Flag3);
if (Flag3==true){
model.setTargetword("3*2+1=7");
}
}
public void setflag1(Boolean flag){
model.setFlag(flag);;
System.out.println("error,the equation is not valid,this will not count as one of tires. so you have "+""+getRemainingAttempts()+" "+"chance ");
}
public void setFlag2(Boolean Flag){
if (Flag==true){
System.out.println(getTargetWord());
}
}
public void setView(NumberleView view) {
this.view = view;
}
public String getTargetWord() {
return model.getTargetWord();
}
public void setRemainingAttempts(int val) {
model.setRemainingAttempts(val);
}
public void processInput(String input) {
model.processInput(input);
}
public boolean isGameOver() {
return model.isGameOver();
}
public boolean isGameWon() {
return model.isGameWon();
}
public void setTargetWord(){
}
}
@@ -0,0 +1,196 @@
package org.example;
import java.io.File;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
import java.io.FileNotFoundException;
public class NumberleModel extends java.util.Observable implements INumberleModel{
private String Word;
public ArrayList<String> List=new ArrayList<>();
public int remainAttempts=6 ;
public boolean Gamewon;
public boolean Flag1=false;
public boolean Flag2=false ;
public boolean Flag3;
public String Formal_World="3+4-2=5";
private StringBuilder CurrentGuess;
//Start new game you should know this function just from txt file to select the words
//which is random to select
public void StartGame(){
if (List == null || List.isEmpty()) {
System.out.println("The list is null or empty. Please check and fix it.");
return;
}
this.FileRead();
Random random = new Random();
int index = random.nextInt(List.size());
if (Flag1){
System.out.println("This is not the correct answer.");
}
if (Flag2){
System.out.println(getTargetWord());
}
if (Flag3){
Word = Formal_World;
} else {
Word = List.get(index);
}
CurrentGuess = new StringBuilder(Word.length());
remainAttempts = Attempt;
Gamewon = false;
setChanged();
notifyObservers();
}
public boolean ProcessInput(String input){
assert input.length() <=7 : "Input length should be <= 7";
if (input.length() < 7){
return false;
}
CurrentGuess = new StringBuilder(input);
if (CurrentGuess.toString().equals(Word)) {
Gamewon = true;
}
setChanged();
notifyObservers();
return Gamewon;
}
public boolean input(String input){
assert input.length() <=7 : "Input length should be <= 7";
if (input.length() < 7){
System.out.println("input length must =7");
}
CurrentGuess = new StringBuilder(input);
if (CurrentGuess.toString().equals(Word)) {
Gamewon = true;
}
else {
remainAttempts--;
}
return Gamewon;
}
public void FileRead(){
try {
File file=new File("C:/Users/93678/IdeaProjects/Numbera/src/equations.txt");
assert file.exists():"File should be exists";
Scanner scanner =new Scanner(file);
while(scanner.hasNextLine()){
this.List.add(scanner.nextLine());
}
scanner.close();
} catch (FileNotFoundException e) {
System.out.println("File can not read,please try to fix it ");
}
}
@Override
public boolean processInput(String input) {
return ProcessInput(input);
}
@Override
public boolean isGameOver() {
assert remainAttempts >= 0 : "remainAttempts should be non-negative";
return remainAttempts <= 0 || Gamewon ;
}
@Override
public boolean isGameWon() {
return Gamewon;
}
@Override
public void setFlag(boolean flag2) {
this.Flag2=flag2;
}
@Override
public void setFlag3(boolean flag3) {
this.Flag3=flag3;
}
@Override
public void setTargetword(String targetword) {
assert targetword != null : "targetword should not be null";
assert targetword.length() >= 7 : "targetword length should be >= 7";
this.Word=targetword;
}
@Override
public String getTargetWord() {
return Word;
}
@Override
public StringBuilder getCurrentGuess() {
return CurrentGuess;
}
@Override
public int getRemainingAttempts() {
assert remainAttempts >= 0 : "remainAttempts should be non-negative";
return remainAttempts;
}
@Override
public void setRemainingAttempts(int val) {
assert val >= 0 : "val should be non-negative";
remainAttempts = val;
}
@Override
public boolean startNewGame() {
StartGame();
return false;
}
@Override
public void Delete() {
if (CurrentGuess.length()>0){
CurrentGuess.deleteCharAt(CurrentGuess.length()-1);
setChanged();
notifyObservers();
}
}
}
+825
View File
@@ -0,0 +1,825 @@
package org.example;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import java.util.Observer;
import net.objecthunter.exp4j.Expression;
import net.objecthunter.exp4j.ExpressionBuilder;
public class NumberleView extends JFrame implements Observer {
private JPanel Panel;//game panel
private JLayeredPane layeredPane;
private NumberleController controller;// Controller
private final INumberleModel model;// Model
public JButton button[][] = new JButton[6][7]; // Game buttons
private JTextField inputTextField;
private int Row = 0;
public static final int ROWS = 6;// Total rows
public static final int COLS = 7;// Total columns
public static final int MAX_INPUT_LENGTH = 7;// Maximum length of input text field
private static final Color CORRECT_COLOR = Color.GREEN; // Correct color
//The entered text contains letters but in the wrong order
private static final Color INCORRECT_COLOR = Color.YELLOW;
private final Color defaultColor = UIManager.getColor("Button.background");// Default button color
//
private JPanel row1;// First row panel
private JPanel row2;// Second row panel
public NumberleView(INumberleModel model, NumberleController controller) {
// Parameter validation
assert model != null; // Ensure model parameter is not null
assert controller != null; // Ensure controller parameter is not null
// Assigning controller and model
this.controller = controller; // Assign controller parameter to the controller field
this.model = model; // Assign model parameter to the model field
// Start new game
controller.startNewGame(); // Invoke startNewGame method of the controller
// Initialize GUI components
initialize(); // Call the initialize method to set up the GUI components
// Show game start reminder
showGameStartReminder(); // Display a reminder or message indicating the game has started
// Register view as observer to model
((NumberleModel) this.model).addObserver(this); // Register this view as an observer to the model
// Set view for controller
this.controller.setView(this); // Set this view instance as the view for the controller
// Update view with initial model state
update((NumberleModel) this.model, null); // Call update method to synchronize view with initial model state
}
public void initialize() {
// Set the look and feel of the user interface to MetalLookAndFeel
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}
// Set the title of the frame
setTitle("Game");
// Set default close operation to exit the application when the frame is closed
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Set the frame size to 800x800 pixels
setSize(750, 750);
setLocationRelativeTo(null);
// Make the frame non-resizable
setResizable(false);
// Set the layout of the frame to BorderLayout
setLayout(new BorderLayout());
// Create a panel with a 6x7 grid layout for buttons
Panel = new JPanel(new GridLayout(6, 7));
// Create buttons and add them to the panel
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
button[i][j] = new JButton("");
button[i][j].setPreferredSize(new Dimension(100, 100));
Panel.add(button[i][j]);
}
// Add the panel to the frame's center position
add(Panel, BorderLayout.CENTER);
Panel.setVisible(true);
}
// Create an input panel with a text field
JPanel inputPanel = new JPanel();
inputTextField = new JTextField(7);
inputPanel.add(inputTextField);
add(inputPanel, BorderLayout.NORTH);
inputPanel.setVisible(false);
// Get text from input text field
String input = inputTextField.getText();
// Assert that input text field is not null or empty
assert (input) != null & !input.isEmpty();
// Create a keyboard panel with numeric buttons and operator buttons
JPanel keyBoardPanel = new JPanel();
keyBoardPanel.setLayout(new BoxLayout(keyBoardPanel, BoxLayout.Y_AXIS));
row1 = new JPanel();
row1.setLayout(new FlowLayout());
for (int i = 1; i <= 9; i++) {
JButton button = new JButton(Integer.toString(i));
button.setFont(new Font("Serif", Font.PLAIN, 30));
button.addActionListener(new ButtonClickListener());
row1.add(button);
}
JButton zeroButton = new JButton("0");
zeroButton.setFont(new Font("Serif", Font.PLAIN, 30));
zeroButton.addActionListener(new ButtonClickListener());
row1.add(zeroButton);
row2 = new JPanel();
row2.setLayout(new FlowLayout());
String[] operators = {"Remove", "+", "-", "*", "/", "=", "Enter"};
for (String operator : operators) {
JButton button = new JButton(operator);
button.setFont(new Font("Serif", Font.PLAIN, 30));
button.addActionListener(new ButtonClickListener());
row2.add(button);
}
keyBoardPanel.add(row1);
keyBoardPanel.add(row2);
// Add the keyboard panel to the frame's south position
add(keyBoardPanel, BorderLayout.SOUTH);
// Create a button panel with various control buttons
JPanel ButtonPanel = new JPanel();
JButton Information = new JButton("How to play");
ButtonPanel.add(Information);
// Add the button panel to the frame's north position
add(ButtonPanel, BorderLayout.WEST);
JButton FixFormual = new JButton("Fixed_Formula");
JButton display = new JButton("Display");
display.addActionListener(e -> {
display();
});
// Add action listeners to control buttons
FixFormual.addActionListener(e -> {
Fixed();
});
Information.addActionListener(e -> {
HowtoPlayGame();
});
// Add buttons to the button panel
ButtonPanel.add(Information);
ButtonPanel.add(FixFormual);
ButtonPanel.add(display);
// Add the button panel to the frame's north position
add(ButtonPanel, BorderLayout.NORTH);
// Make the frame visible
setVisible(true);
// Call the change method
change();
}
public void Fixed() {
controller.SetFlag(true);
System.out.println(controller.getTargetWord());
}
/**
* Removes all components from row2 panel and replaces them with operator buttons in a specific order.
* This method is called when the "Swap" button is clicked.
*/
public void display() {
controller.setFlag2(true);
}
/**
* Updates the buttons based on the input text.
* This method is called when there is a change in the input text field.
*/
public void change() {
String input = inputTextField.getText();
updateButtonsFromInput(input);
}
/**
* ActionListener implementation for handling button clicks.
*/
private class ButtonClickListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
JButton source = (JButton) e.getSource();
String buttonText = source.getText();
switch (buttonText) {
case "Remove":
clearDisplay();
break;
case "Enter":
Enter();
break;
default:
if (inputTextField.getText().length() < MAX_INPUT_LENGTH) {
updateDisplay(buttonText);
updateButtonsFromInput(inputTextField.getText());
}
controller.isGameOver();
}
}
}
/**
* Updates the color and text of buttons based on the target word and user input.
*
* @param target The target word as an array of characters.
* @param input The user input as a string.
*/
private void updateButtonsFromTarget(char[] target, String input) {
char[] userInput = input.toCharArray();
for (int col = 0; col < 7; col++) {
char targetChar = target[col];
char inputChar = userInput[col];
if (targetChar == inputChar) {
button[Row][col].setBackground(Color.GREEN);
} else if (new String(target).indexOf(inputChar) != -1) {
button[Row][col].setBackground(Color.ORANGE);
} else {
button[Row][col].setBackground(Color.GRAY);
}
button[Row][col].setText(String.valueOf(inputChar));
String buttonText = button[Row][col].getText();
for (Component component : row1.getComponents()) {
if (component instanceof JButton) {
JButton keyboardButton = (JButton) component;
if (keyboardButton.getText().equals(buttonText)) {
if (targetChar == inputChar) {
keyboardButton.setBackground(Color.GREEN);
} else if (new String(target).indexOf(inputChar) != -1) {
keyboardButton.setBackground(Color.ORANGE);
} else {
keyboardButton.setBackground(Color.GRAY);
}
break;
}
}
}
for (Component component : row2.getComponents()) {
if (component instanceof JButton) {
JButton keyboardButton = (JButton) component;
if (keyboardButton.getText().equals(buttonText)) {
if (targetChar == inputChar) {
keyboardButton.setBackground(Color.GREEN);
} else if (new String(target).indexOf(inputChar) != -1) {
keyboardButton.setBackground(Color.ORANGE);
} else {
keyboardButton.setBackground(Color.GRAY);
}
break;
}
}
}
}
}
/**
* Updates the text of buttons based on the user input.
*
* @param input The user input as a string.
*/
private void updateButtonsFromInput(String input) {
int rowIndex = Row;
int colIndex = 0;
char[] chars = input.toCharArray();
for (char c : chars) {
if (Character.isDigit(c) || "+-*/=".indexOf(c) != -1) {
if (colIndex < 7) {
button[rowIndex][colIndex].setText(String.valueOf(c));
colIndex++;
}
}
}
for (int clearIndex = colIndex; clearIndex < 7; clearIndex++) {
button[rowIndex][clearIndex].setText("");
}
}
/**
* Handles the action when the "Enter" button is clicked.
*/
public void Enter() {
String input = inputTextField.getText();
// Check if input length is less than 7
if (input.length() < 7) {
controller.setflag1(true);
TooShort();
return; // Return to avoid further processing
}
boolean containsOperator = false; // Flag to check if an operator is present
for (char c : input.toCharArray()) {
if ("+-*/".indexOf(c) != -1) {
containsOperator = true; // Set flag if an operator is found
break;
}
}
if (input.length() == 7) {
boolean containsEquals = input.contains("=");
boolean containsMultiple = input.contains("+-*/");
boolean containMultiples = input.contains("+-/");
boolean containMultipless = input.contains("+-*");
boolean contains = input.contains("+=++");
if (!containsEquals) {
NoEqualSign();
} else if (!containsOperator) {
Symobol();
} else if (containsMultiple || containMultiples || containMultipless) {
MultiplyOperator();
} else if (contains) {
MultiplyOperator();
} else {
boolean isCorrect = validateEquation(input);
if (isCorrect) {
char[] target = controller.getTargetWord().toCharArray();
validateEquation(input);
controller.setRemainingAttempts(controller.getRemainingAttempts() - input.length() / 7);
updateButtonsFromInput(input); // Update buttons based on the input4
updateButtonsFromTarget(target, input);
Row++;
if (Row > 5) {
Row = 0;
}
controller.processInput(input);
inputTextField.setText(""); // Clear the input text field
if (controller.getRemainingAttempts() == 0) {
Youlost();
}
} else {
NotEqual();
}
}
}
}
/**
* Validates the equation provided by the user.
*
* @param input The equation input by the user.
* @return True if the equation is valid, false otherwise.
*/
private boolean validateEquation(String input) {
String[] parts = input.split("="); // Split the input into left and right sides of the equation
if (parts.length != 2) {
return false; // Return false if the equation doesn't contain exactly one equals sign
}
// Evaluate the left side of the equation
Expression expLeft = new ExpressionBuilder(parts[0].trim()).build();
double leftResult = expLeft.evaluate();
// Evaluate the right side of the equation
Expression expRight = new ExpressionBuilder(parts[1].trim()).build();
double rightResult = expRight.evaluate();
// Compare the results of the left and right sides of the equation
return Double.compare(leftResult, rightResult) == 0;
}
/**
* Clears the display by removing the last character from the input text field.
*/
public void clearDisplay() {
String currentText = inputTextField.getText();
if (!currentText.isEmpty()) {
// Remove the last character from the current text
String newText = currentText.substring(0, currentText.length() - 1);
inputTextField.setText(newText);
// Update buttons based on the new input text
updateButtonsFromInput(newText);
}
}
/**
* Updates the display by appending the given text to the input text field.
* If the length of the resulting text exceeds 7 characters, it truncates the text appropriately.
*
* @param text The text to be added to the input text field.
*/
public void updateDisplay(String text) {
// Check if adding the text will exceed the maximum length
if (inputTextField.getText().length() + text.length() > 7) {
// Truncate the text to fit within the maximum length
text = text.substring(0, 7 - inputTextField.getText().length());
}
// Append the text to the input text field
inputTextField.setText(inputTextField.getText() + text);
}
/**
* Displays a reminder frame indicating that the input is too short.
* The reminder frame is displayed for 2 seconds before automatically closing.
*/
public void TooShort() {
// Create a reminder frame
JFrame reminderFrame = new JFrame("reminder");
reminderFrame.setBounds(625, 300, 400, 200);
reminderFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// Create a label for the reminder message
JLabel reminderLabel = new JLabel("Too Short !");
reminderLabel.setFont(new Font("Serif", Font.BOLD, 25));
reminderLabel.setHorizontalAlignment(JLabel.CENTER);
// Create a panel to hold the reminder label
JPanel reminderPanel = new JPanel(new BorderLayout());
reminderPanel.add(reminderLabel, BorderLayout.CENTER);
reminderFrame.getContentPane().add(reminderPanel);
// Make the reminder frame visible
reminderFrame.setVisible(true);
// Set a timer to automatically close the reminder frame after 2 seconds
Timer timer = new Timer(2000, e -> {
reminderFrame.dispose();
});
timer.setRepeats(false);
timer.start();
}
/**
* Displays a reminder frame indicating that there must be at least one mathematical symbol
* +- * / The reminder frame is displayed for 2 seconds before automatically closing.
*/
public void MultiplyOperator() {
// Create a reminder frame
JFrame reminderFrame = new JFrame("reminder");
reminderFrame.setBounds(625, 300, 400, 200);
reminderFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// Create a label for the reminder message
JLabel reminderLabel = new JLabel("Multiple math symbols in a row ");
reminderLabel.setFont(new Font("Serif", Font.BOLD, 25));
reminderLabel.setHorizontalAlignment(JLabel.CENTER);
// Create a panel to hold the reminder label
JPanel reminderPanel = new JPanel(new BorderLayout());
reminderPanel.add(reminderLabel, BorderLayout.CENTER);
reminderFrame.getContentPane().add(reminderPanel);
// Make the reminder frame visible
reminderFrame.setVisible(true);
// Set a timer to automatically close the reminder frame after 2 seconds
Timer timer = new Timer(2000, e -> {
reminderFrame.dispose();
});
timer.setRepeats(false);
timer.start();
}
/**
* Displays a reminder frame indicating that there
* they must be at least one sign
*/
public void Symobol() {
// Create a reminder frame
JFrame reminderFrame = new JFrame("reminder");
reminderFrame.setBounds(625, 300, 400, 200);
reminderFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// Create a label for the reminder message
JLabel reminderLabel = new JLabel("There must be at least one sign +-*/ !");
reminderLabel.setFont(new Font("Serif", Font.BOLD, 25));
reminderLabel.setHorizontalAlignment(JLabel.CENTER);
// Create a panel to hold the reminder label
JPanel reminderPanel = new JPanel(new BorderLayout());
reminderPanel.add(reminderLabel, BorderLayout.CENTER);
reminderFrame.getContentPane().add(reminderPanel);
// Make the reminder frame visible
reminderFrame.setVisible(true);
// Set a timer to automatically close the reminder frame after 2 seconds
Timer timer = new Timer(2000, e -> {
reminderFrame.dispose();
});
timer.setRepeats(false);
timer.start();
}
/**
* Displays a reminder frame explaining how to play the game.
* The reminder frame contains instructions on how to guess the hidden mathematical equation in 6 tries
* and how the color of the tiles changes to show the proximity to the correct solution.
* The reminder frame is displayed until closed by the user.
*/
public void HowtoPlayGame() {
// Create a frame to display the instructions
JFrame reminderFrame = new JFrame("How to play");
reminderFrame.setBounds(420, 150, 850, 850);
reminderFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// Create a text area to display the instructions
JTextArea textArea = new JTextArea();
textArea.setLineWrap(true); // Enable automatic line wrapping
textArea.setWrapStyleWord(true);
textArea.setText("游戏的规则。游戏的目标是在6次尝试内猜出隐藏的数学方程式,并猜出方块的颜色。玩家需要输入一个数学方程式,然后根据提示来猜测正确的方程式以及方块的颜色。例如,如果隐藏的方程式是5+75=40,而玩家输入了5+52=10,那么根据位置正确与否,以及数字正确与否,某些部分的方块会变成绿色来指示正确的部分。 "
);
// Set font and size for the text area
textArea.setFont(new Font("Serif", Font.ROMAN_BASELINE, 30));
// Create a panel to hold the text area
JPanel reminderPanel = new JPanel(new BorderLayout());
reminderPanel.add(textArea, BorderLayout.CENTER);
reminderFrame.getContentPane().add(reminderPanel);
// Make the reminder frame visible
reminderFrame.setVisible(true);
}
/**
* Displays a reminder frame indicating that the left side of the equation is not equal to the right side.
* Displays a reminder frame indicating that the left side of the equation is not equal to the right side.
*/
public void NotEqual() {
// Create a frame to display the reminder
JFrame reminderFrame = new JFrame("reminder");
reminderFrame.setBounds(625, 300, 500, 400);
reminderFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// Create a label to display the reminder message
JLabel reminderLabel = new JLabel("The left side is not equal to the right");
reminderLabel.setFont(new Font("Serif", Font.BOLD, 25));
reminderLabel.setHorizontalAlignment(JLabel.CENTER);
// Create a panel to hold the label
JPanel reminderPanel = new JPanel(new BorderLayout());
reminderPanel.add(reminderLabel, BorderLayout.CENTER);
reminderFrame.getContentPane().add(reminderPanel);
// Make the reminder frame visible
reminderFrame.setVisible(true);
// Close the reminder frame after a delay
Timer timer = new Timer(2000, e -> {
reminderFrame.dispose();
});
timer.setRepeats(false);
timer.start();
}
/**
* Displays a reminder frame indicating the game start and prompts the user to guess the first equation.
* The reminder frame is displayed until closed by the user.
*/
private void showGameStartReminder() {
// Create a frame to display the reminder
JFrame reminderFrame = new JFrame("reminder");
reminderFrame.setBounds(625, 300, 450, 300);
reminderFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// Create a label to display the reminder message
JLabel reminderLabel = new JLabel("Guess the first equation!");
reminderLabel.setFont(new Font("Serif", Font.BOLD, 25));
reminderLabel.setHorizontalAlignment(JLabel.CENTER);
// Create a panel to hold the label
JPanel reminderPanel = new JPanel(new BorderLayout());
reminderPanel.setBackground(Color.RED);
reminderPanel.add(reminderLabel, BorderLayout.CENTER);
reminderFrame.getContentPane().add(reminderPanel);
// Make the reminder frame visible
reminderFrame.setVisible(true);
// Close the reminder frame after a delay
Timer timer = new Timer(2000, e -> {
reminderFrame.dispose();
});
timer.setRepeats(false);
timer.start();
}
/**
* Displays a reminder frame indicating that there is no equal (=) sign in the input.
* The reminder frame is displayed until closed by the user.
*/
public void NoEqualSign() {
// Create a frame to display the reminder
JFrame reminderFrame = new JFrame("reminder");
reminderFrame.setBounds(625, 300, 400, 200);
reminderFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// Create a label to display the reminder message
JLabel reminderLabel = new JLabel("No equal (=) sign!");
reminderLabel.setFont(new Font("Serif", Font.BOLD, 25));
reminderLabel.setHorizontalAlignment(JLabel.CENTER);
// Create a panel to hold the label
JPanel reminderPanel = new JPanel(new BorderLayout());
reminderPanel.add(reminderLabel, BorderLayout.CENTER);
reminderFrame.getContentPane().add(reminderPanel);
// Make the reminder frame visible
reminderFrame.setVisible(true);
// Close the reminder frame after a delay
Timer timer = new Timer(2000, e -> {
reminderFrame.dispose();
});
timer.setRepeats(false);
timer.start();
}
/**
* Displays a reminder frame indicating that the player has lost the game.
* Provides an option to replay the game.
*/
public void Youlost() {
// Create a frame to display the reminder
JFrame reminderFrame = new JFrame("reminder");
reminderFrame.setBounds(625, 300, 400, 200);
reminderFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// Create a button for replaying the game
Button Replay = new Button("Replay");
Replay.addActionListener(e -> {
controller.startNewGame();
System.out.println("you replay the game so the number become " + " " + controller.getTargetWord());
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
button[row][col].setText("");
button[row][col].setBackground(defaultColor);
}
}
// Enable buttons for input
for (Component component : row1.getComponents()) {
if (component instanceof JButton) {
component.setEnabled(true);
component.setBackground(defaultColor);
}
}
// Enable operator buttons
for (Component component : row2.getComponents()) {
if (component instanceof JButton) {
component.setEnabled(true);
component.setBackground(defaultColor);
}
}
// Close the reminder frame
reminderFrame.dispose();
});
Replay.setBounds(10, 20, 10, 10);
// Create a label to display the reminder message
JLabel reminderLabel = new JLabel("You lost!");
reminderLabel.setFont(new Font("Serif", Font.BOLD, 25));
reminderLabel.setHorizontalAlignment(JLabel.CENTER);
// Create a panel to hold the label and replay button
JPanel reminderPanel = new JPanel(new BorderLayout());
reminderPanel.add(reminderLabel, BorderLayout.CENTER);
reminderPanel.add(Replay, BorderLayout.NORTH);
// Add the panel to the reminder frame
reminderFrame.getContentPane().add(reminderPanel);
// Make the replay button and reminder frame visible
Replay.setVisible(true);
reminderFrame.setVisible(true);
}
/**
* Displays a reminder frame indicating that the player has won the game.
* Provides an option to replay the game.
*/
public void Youwon() {
// Create a frame to display the reminder
JFrame reminderFrame = new JFrame("reminder");
reminderFrame.setBounds(625, 300, 400, 200);
reminderFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// Create a button for restarting the game
Button Restart = new Button("Replay");
Restart.addActionListener(e -> {
Row = 0;
// Reset the game board
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
button[row][col].setText("");
button[row][col].setBackground(defaultColor);
}
}
// Enable buttons for input
for (Component component : row1.getComponents()) {
if (component instanceof JButton) {
component.setEnabled(true);
component.setBackground(defaultColor);
}
}
// Enable operator buttons
for (Component component : row2.getComponents()) {
if (component instanceof JButton) {
component.setEnabled(true);
component.setBackground(defaultColor);
}
}
// Close the reminder frame
reminderFrame.dispose();
});
Restart.setBounds(10, 20, 10, 10);
// Create a label to display the reminder message
JLabel reminderLabel = new JLabel("You won!");
reminderLabel.setFont(new Font("Serif", Font.BOLD, 25));
reminderLabel.setHorizontalAlignment(JLabel.CENTER);
// Create a panel to hold the label and restart button
JPanel reminderPanel = new JPanel(new BorderLayout());
reminderPanel.add(reminderLabel, BorderLayout.CENTER);
reminderPanel.add(Restart, BorderLayout.NORTH);
// Add the panel to the reminder frame
reminderFrame.getContentPane().add(reminderPanel);
// Make the restart button and reminder frame visible
Restart.setVisible(true);
reminderFrame.setVisible(true);
}
@Override
/**
* update the GUI ,If the view is change the observable will notice changed
*
*/
public void update(Observable o, Object arg) {
if (controller.isGameOver()) {
if (controller.isGameWon()) {
Youwon();
controller.startNewGame();
System.out.println("The new number is" + " " + controller.getTargetWord());
}
for (Component component : row1.getComponents()) {
if (component instanceof JButton) {
component.setEnabled(false);
}
}
for (Component component : row2.getComponents()) {
if (component instanceof JButton) {
component.setEnabled(false);
}
}
}
}
}