- Full TTT game. Does not count diagonals as win yet

Signed-off-by: HeshamTB <hishaminv@gmail.com>
This commit is contained in:
HeshamTB 2020-11-25 23:50:17 +03:00
parent 6da9aef3ad
commit 2236eb3f85
12 changed files with 431 additions and 0 deletions

3
lab-06/.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

23
lab-06/.idea/compiler.xml Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
<resourceExtensions />
<wildcardResourcePatterns>
<entry name="!?*.java" />
<entry name="!?*.form" />
<entry name="!?*.class" />
<entry name="!?*.groovy" />
<entry name="!?*.scala" />
<entry name="!?*.flex" />
<entry name="!?*.kt" />
<entry name="!?*.clj" />
</wildcardResourcePatterns>
<annotationProcessing>
<profile default="true" name="Default" enabled="false">
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

4
lab-06/.idea/gradle.xml Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
</project>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="lib">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../lib" />
</CLASSES>
<JAVADOC />
<SOURCES />
<jarDirectory url="file://$PROJECT_DIR$/../../lib" recursive="false" />
</library>
</component>

9
lab-06/.idea/misc.xml Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectKey">
<option name="state" value="project://e79810c8-c5c8-43b1-b19c-90c1f4095425" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
lab-06/.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/lab-06.iml" filepath="$PROJECT_DIR$/lab-06.iml" />
</modules>
</component>
</project>

125
lab-06/.idea/uiDesigner.xml Normal file
View File

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

6
lab-06/.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

12
lab-06/lab-06.iml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="lib" level="project" />
</component>
</module>

209
lab-06/src/GamePane.java Normal file
View File

@ -0,0 +1,209 @@
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class GamePane extends GridPane implements EventHandler<MouseEvent> {
private Button btnExit;
private Button btnRestart;
private Button[][] btnGame;
private boolean done;
public GamePane(){
setPadding(new Insets(5,5,5,5));
//setVgap(5);
//setHgap(5);
setAlignment(Pos.CENTER);
//setMinSize(400, 200);
makeButtons();
}
@Override
public void handle(MouseEvent mouseEvent) {
if (mouseEvent.getSource() instanceof Button){
Button pressedButton = (Button) mouseEvent.getSource();
if (pressedButton.getText().equalsIgnoreCase("-")){
pressedButton.setText("X");
play();
try {
checkWin();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public void restart() {
System.out.println("Starting new game");
for (int i = 0; i < btnGame.length; i++) {
//Element
for (int j = 0; j < btnGame[i].length; j++) {
btnGame[i][j].setText("-");
}
}
done = false;
}
private void play() {
/*
From the example application, it seems the 'CPU' is not playing a 'smart' game.
To me it seems random. For now, 'CPU' plays a random move, however, this seems
like a great problem to tackle and make the play() 'smart'.
- H.B.
*/
boolean played = false;
while (!played && hasEmpty()){
int x = getRandom(0,3);
int y = getRandom(0,3);
Button btn = btnGame[y][x];
if (btn.getText().equalsIgnoreCase("-")) {
btn.setText("O");
played = true;
}
}
}
private void checkWin() throws Exception {
//check horizontal
for (int i = 0; i < 3; i++){
int xCount = 0;
int oCount = 0;
for (int j = 0; j < 3; j++) {
if (btnGame[i][j].getText().equalsIgnoreCase("X")) xCount++;
else if (btnGame[i][j].getText().equalsIgnoreCase("O")) oCount++;
}
if (xCount == 3 && !done) {
announceWin(Player.HUMAN);
} else if (oCount == 3 && !done) {
announceWin(Player.CPU);
}
}
//check vertical
for (int i = 0; i < 3; i++){
int xCount = 0;
int oCount = 0;
for (int j = 0; j < 3; j++) {
if (btnGame[j][i].getText().equalsIgnoreCase("X")) xCount++;
else if (btnGame[j][i].getText().equalsIgnoreCase("O")) oCount++;
}
if (xCount == 3 && !done) {
announceWin(Player.HUMAN);
}
else if (oCount == 3 && !done) {
announceWin(Player.CPU);
}
}
//First diagonal
for (int i = 0; i < 3; i++) {
int xCount = 0;
int oCount = 0;
if (btnGame[i][i].getText().equalsIgnoreCase("X")) xCount++;
else if (btnGame[i][i].getText().equalsIgnoreCase("O")) oCount++;
if (xCount == 3 && !done) {
announceWin(Player.HUMAN);
}
else if (oCount == 3 && !done){
announceWin(Player.CPU);
}
}
//Second diagonal
for (int i = 0; i < 3; i++) {
int xCount = 0;
int oCount = 0;
if (btnGame[2-i][i].getText().equalsIgnoreCase("X")) xCount++;
else if (btnGame[2-i][i].getText().equalsIgnoreCase("O")) oCount++;
if (xCount == 3 && !done){
announceWin(Player.HUMAN);
}
else if (oCount == 3 && !done){
announceWin(Player.CPU);
}
}
}
private void announceWin(Player player) throws Exception {
done = true;
WinDialog w = new WinDialog(player);
w.start(new Stage());
}
private void makeButtons() {
btnExit = new Button("Exit");
btnExit.setOnMouseClicked(e -> System.exit(0));
btnExit.setPrefSize(80,80);
btnRestart = new Button("New\nGame");
btnRestart.setOnMouseClicked(e -> restart());
btnRestart.setPrefSize(80,80);
btnGame = new Button[3][3];
//Rows
for (int i = 0; i < btnGame.length; i++) {
//Element
for (int j = 0; j < btnGame[i].length; j++) {
btnGame[i][j] = new Button("-");
btnGame[i][j].setOnMouseClicked(this);
btnGame[i][j].setPrefSize(80,80);
add(btnGame[i][j], i, j);
}
}
add(btnRestart, 0,btnGame.length+1 );
add(btnExit, 1,btnGame.length+1);
}
private int getRandom(double min, double max) {
return (int)(Math.random() * (max - min) + min);
}
private boolean hasEmpty() {
for (Button[] btnRow : btnGame)
for (Button btn : btnRow)
if (btn.getText().equalsIgnoreCase("-"))
return true;
return false;
}
private enum Player {
HUMAN,
CPU
}
private static class WinDialog extends Application {
private final Player winner;
public WinDialog(Player player){
this.winner = player;
}
@Override
public void start(Stage stage) throws Exception {
VBox root = new VBox();
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(15,15,15,15));
root.setSpacing(10);
Button btn = new Button("OK");
btn.setOnMouseClicked(e -> {
stage.close();
System.out.println("[Dialog] Exit button clicked");
});
root.getChildren().add(new Text(this.winner.name() + " won!"));
root.getChildren().add(btn);
stage.setScene(new Scene(root,200,100));
stage.show();
}
}
}

16
lab-06/src/Main.java Normal file
View File

@ -0,0 +1,16 @@
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage stage) throws Exception {
GamePane game = new GamePane();
stage.setScene(new Scene(game));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}