From a1593664820415582c1e3440bebb65fe2c14d534 Mon Sep 17 00:00:00 2001 From: STELLSAN Date: Thu, 30 May 2024 22:55:21 +0300 Subject: [PATCH 1/2] add_task_6 --- pom.xml | 58 +++++ report/Nedelin_screen.png | Bin 0 -> 13139 bytes src/main/java/Program.java | 328 +++++++++++++++++++++++++ src/main/java/org/example/App.java | 13 + src/test/java/GameTests.java | 102 ++++++++ src/test/java/PlayerTests.java | 36 +++ src/test/java/TicTacToeCellTests.java | 45 ++++ src/test/java/org/example/AppTest.java | 38 +++ 8 files changed, 620 insertions(+) create mode 100644 pom.xml create mode 100644 report/Nedelin_screen.png create mode 100644 src/main/java/Program.java create mode 100644 src/main/java/org/example/App.java create mode 100644 src/test/java/GameTests.java create mode 100644 src/test/java/PlayerTests.java create mode 100644 src/test/java/TicTacToeCellTests.java create mode 100644 src/test/java/org/example/AppTest.java diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8ad1b61 --- /dev/null +++ b/pom.xml @@ -0,0 +1,58 @@ + + 4.0.0 + + org.example + ST-6 + 1.0-SNAPSHOT + jar + + ST-6 + http://maven.apache.org + + + 8 + 8 + UTF-8 + + + + + junit + junit + 4.13.2 + test + + + org.junit.jupiter + junit-jupiter + RELEASE + test + + + + + + + + org.jacoco + jacoco-maven-plugin + 0.8.5 + + + + prepare-agent + + + + generate-code-coverage-report + test + + report + + + + + + + diff --git a/report/Nedelin_screen.png b/report/Nedelin_screen.png new file mode 100644 index 0000000000000000000000000000000000000000..e9e8e8e38f7d873285d862c09b74ac50bac39210 GIT binary patch literal 13139 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 literal 0 HcmV?d00001 diff --git a/src/main/java/Program.java b/src/main/java/Program.java new file mode 100644 index 0000000..45b87b0 --- /dev/null +++ b/src/main/java/Program.java @@ -0,0 +1,328 @@ +// Copyright 2024 by Nedelin Dmitry + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import java.util.ArrayList; +import java.util.Random; +import java.io.FileWriter; +import java.io.PrintWriter; +import java.io.IOException; + +enum Condition { PLAYING, OWIN, XWIN, DRAW }; + + +class Player { + public char symbol; + public int move; + public boolean selected; + public boolean win; +} + +class Game { + public Condition condition; + public Player PC1, PC2; + public Player rn_player; + public int last_rnmove; + public char symbol; + public static final int INF = 100; + public int q; + public char[] field; + + + public Game() { + PC1 =new Player(); + PC2 =new Player(); + PC1.symbol='X'; + PC2.symbol='O'; + condition = Condition.PLAYING; + field =new char[9]; + for(int i=0;i<9;i++) + field[i]=' '; + } + + // возвращаем состояние игры + public Condition checkState(char[] board) + { + //char symbol=game.symbol;//cplayer.symbol; + Condition condition = Condition.PLAYING; + if ((board[0] == symbol && board[1] == symbol && board[2] == symbol) || + (board[3] == symbol && board[4] == symbol && board[5] == symbol) || + (board[6] == symbol && board[7] == symbol && board[8] == symbol) || + (board[0] == symbol && board[3] == symbol && board[6] == symbol) || + (board[1] == symbol && board[4] == symbol && board[7] == symbol) || + (board[2] == symbol && board[5] == symbol && board[8] == symbol) || + (board[0] == symbol && board[4] == symbol && board[8] == symbol) || + (board[2] == symbol && board[4] == symbol && board[6] == symbol)) + { + if (symbol == 'X') + condition = Condition.XWIN; + else if (symbol == 'O') + condition = Condition.OWIN; + } + else { + condition = Condition.DRAW; + for (int i = 0; i < 9; i++) + { + if (board[i] == ' ') { + condition = Condition.PLAYING; + break; + } + } + } + return condition; + } + + void MovesGenerator(char[] board, ArrayList move_list) { + for (int i = 0; i < 9; i++) + if (board[i] == ' ') + move_list.add(i); + } + + int evaluatePosition(char[] board, Player player) + { + Condition condition =checkState(board); + if ((condition == Condition.XWIN || condition == Condition.OWIN || condition == Condition.DRAW)) + { + if ((condition == Condition.XWIN && player.symbol == 'X') || (condition == Condition.OWIN && player.symbol == 'O')) + return +Game.INF; + else if ((condition == Condition.XWIN && player.symbol == 'O') || (condition == Condition.OWIN && player.symbol == 'X')) + return -Game.INF; + else if (condition == Condition.DRAW) + return 0; + } + return -1; + } + + int MinMaxMove(char[] board, Player player) + { + int best_val = -Game.INF, index = 0; + ArrayList move_list=new ArrayList<>(); + int[] best_moves = new int[9]; + + MovesGenerator(board, move_list); + + while (move_list.size()!=0) { + board[move_list.get(0)] = player.symbol; + symbol = player.symbol; + + int val = MinMove(board, player); + + if (val > best_val) { + best_val = val; + index = 0; + best_moves[index] = move_list.get(0)+1; + } + else if (val == best_val) + best_moves[++index] = move_list.get(0)+1; + + System.out.printf("\nMinMaxMove: %3d(%1d) ", 1 + move_list.get(0), val); + board[move_list.get(0)] = ' '; + move_list.remove(0); + } + if (index > 0) { + Random r = new Random(); + index = r.nextInt(index); + } + + System.out.printf("\nMinMaxMove best: %3d(%1d) ", best_moves[index], best_val); + System.out.printf("Steps count: %d", q); + q = 0; + return best_moves[index]; + } + + int MinMove(char[] board, Player player) { + + int positionValue = evaluatePosition(board, player); + if (positionValue != -1) + return positionValue; + q++; + int best_val = +Game.INF; + ArrayList move_list=new ArrayList<>(); + + MovesGenerator(board, move_list); + + while (move_list.size()!=0) { + symbol= (player.symbol == 'X') ? 'O' : 'X'; + board[move_list.get(0)] = symbol; + + int val = MaxMove(board, player); + + if (val < best_val) { + best_val = val; + } + board[move_list.get(0)] = ' '; + move_list.remove(0); + } + return best_val; + } + + int MaxMove(char[] board, Player player) { + int pos_value = evaluatePosition(board, player); + if (pos_value != -1) + return pos_value; + q++; + int best_val = -Game.INF; + ArrayList move_list=new ArrayList<>(); + MovesGenerator(board, move_list); + while (move_list.size()!=0) { + symbol=(player.symbol == 'X') ? 'X' : 'O'; + board[move_list.get(0)] = symbol; + int val = MinMove(board, player); + if (val > best_val) { + best_val = val; + } + board[move_list.get(0)] = ' '; + move_list.remove(0); + } + return best_val; + } +} + +public class Program { + + public static FileWriter fileWriter; + public static PrintWriter printWriter; + public static void main(String[] args) throws IOException { + JFrame frame = new JFrame("Demo"); + frame.add(new TicTacToePanel(new GridLayout(3,3))); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setBounds(5, 5, 500, 500); + frame.setVisible(true); + } +} + +class TicTacToeCell extends JButton { + private boolean isFill; + private int num; + private int row; + private int col; + private char marker; + + public TicTacToeCell(int num,int x,int y) { + this.num=num; + row=y; + col=x; + marker=' '; + setText(Character.toString(marker)); + setFont(new Font("Arial", Font.PLAIN, 40)); + } + public void setMarker(String m) { + marker=m.charAt(0); + setText(m); + setEnabled(false); + } + public char getMarker() { + return marker; + } + public int getRow() { + return row; + } + public int getCol() { + return col; + } + public int getNum() { + return num; + } + +} + +class Utility { + + public static void print(char[] board) { + System.out.println(); + for(int j=0;j<9;j++) + System.out.print(board[j]+"-"); + System.out.println(); + } + public static void print(int[] board) { + System.out.println(); + for(int j=0;j<9;j++) + System.out.print(board[j]+"-"); + System.out.println(); + } + public static void print(ArrayList moves) { + System.out.println(); + for(int j=0;j0) + cells[game.PC2.move-1].doClick(); + } + else + { + game.last_rnmove = game.PC1.move; + game.symbol = game.PC1.symbol; + game.rn_player = game.PC1; + } + + game.condition =game.checkState(game.field); + + + if(game.condition == Condition.XWIN) { + JOptionPane.showMessageDialog(null,"Выиграли крестики","Результат", JOptionPane.WARNING_MESSAGE); + System.exit(0); + + } + else if(game.condition == Condition.OWIN) { + JOptionPane.showMessageDialog(null,"Выиграли нолики","Результат", JOptionPane.WARNING_MESSAGE); + System.exit(0); + } + else if(game.condition == Condition.DRAW) { + JOptionPane.showMessageDialog(null,"Ничья","Результат", JOptionPane.WARNING_MESSAGE); + System.exit(0); + } + } +} + + diff --git a/src/main/java/org/example/App.java b/src/main/java/org/example/App.java new file mode 100644 index 0000000..5f21d2e --- /dev/null +++ b/src/main/java/org/example/App.java @@ -0,0 +1,13 @@ +package org.example; + +/** + * Hello world! + * + */ +public class App +{ + public static void main( String[] args ) + { + System.out.println( "Hello World!" ); + } +} diff --git a/src/test/java/GameTests.java b/src/test/java/GameTests.java new file mode 100644 index 0000000..98cdda9 --- /dev/null +++ b/src/test/java/GameTests.java @@ -0,0 +1,102 @@ +// Copyright 2024 by Nedelin Dmitry +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.ArrayList; + +public class GameTests { + Game game; + + @BeforeEach + public void setUp() { + game = new Game(); + } + + @Test + public void testConditions() { + assertEquals(Condition.PLAYING, game.condition); + assertEquals('X', game.PC1.symbol); + assertEquals('O', game.PC2.symbol); + assertEquals(' ', game.field[0]); + } + + @Test + public void testCheckConditions() { + Condition condition = game.checkState(game.field); + assertEquals(Condition.PLAYING, condition); + } + + @Test + public void testCheckConditionXWin() { + game.symbol = 'X'; + char[] field = {'X', 'X', 'X', 'O', 'O', ' ', ' ', ' '}; + Condition condition = game.checkState(field); + assertEquals(Condition.XWIN, condition); + } + + @Test + public void testCheckConditionOWin() { + game.symbol = 'O'; + char[] field = {'O', 'O', 'O', 'X', 'X', ' ', 'X', 'X', ' '}; + Condition condition = game.checkState(field); + assertEquals(Condition.OWIN, condition); + } + + @Test + public void testCheckConditionDrawing() { + game.symbol = 'X'; + char[] field = {'X', 'X', 'O', 'O', 'O', 'X', 'O', 'X', 'O'}; + Condition condition = game.checkState(field); + assertEquals(Condition.DRAW, condition); + } + + @Test + public void testMovesGenerator() { + ArrayList moves = new ArrayList<>(); + game.MovesGenerator(game.field, moves); + assertEquals(9, moves.size()); + } + + @Test + public void testEvaluateFirstPCWin() { + game.symbol = 'X'; + for (int i = 0; i < 3; i++) { + game.field[i] = game.symbol; + } + + int result = game.evaluatePosition(game.field, game.PC1); + assertEquals(Game.INF, result); + result = game.evaluatePosition(game.field, game.PC2); + assertEquals(-Game.INF, result); + } + + @Test + public void testEvaluateSecondPlayerWin() { + game.symbol = 'O'; + for (int i = 0; i < 3; i++) { + game.field[i] = game.symbol; + } + + int result = game.evaluatePosition(game.field, game.PC1); + assertEquals(-Game.INF, result); + result = game.evaluatePosition(game.field, game.PC2); + assertEquals(Game.INF, result); + } + + @Test + public void testEvaluatePositionDraw() { + game.symbol = 'X'; + game.field = new char[] {'X', 'X', 'O', 'O', 'O', 'X', 'O', 'X', 'O'}; + int result = game.evaluatePosition(game.field, game.PC1); + assertEquals(0, result); + } + + @Test + public void testMinimax() { + game.symbol = 'X'; + game.field = new char[] {'X', ' ', 'O', ' ', ' ', 'X', ' ', 'X', 'O'}; + int move = game.MinMaxMove(game.field, game.PC2); + assertTrue(move >= 1 && move <= 9); + } +} diff --git a/src/test/java/PlayerTests.java b/src/test/java/PlayerTests.java new file mode 100644 index 0000000..0e940e3 --- /dev/null +++ b/src/test/java/PlayerTests.java @@ -0,0 +1,36 @@ +// Copyright 2024 by Nedelin Dmitry +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class PlayerTests { + private Player player; + + @BeforeEach + public void setUp() { + player = new Player(); + } + + @Test + public void testValues() { + assertFalse(player.selected); + assertFalse(player.win); + assertEquals(0, player.move); + + player.selected = true; + player.win = true; + player.move = 5; + assertTrue(player.selected); + assertTrue(player.win); + assertEquals(5, player.move); + } + + @Test + public void testSymbol() { + player.symbol = 'X'; + assertEquals('X', player.symbol); + + player.symbol = 'O'; + assertEquals('O', player.symbol); + } +} diff --git a/src/test/java/TicTacToeCellTests.java b/src/test/java/TicTacToeCellTests.java new file mode 100644 index 0000000..54fb9e8 --- /dev/null +++ b/src/test/java/TicTacToeCellTests.java @@ -0,0 +1,45 @@ +// Copyright 2024 by Nedelin Dmitry +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + + +public class TicTacToeCellTests { + private TicTacToeCell cell; + + @BeforeEach + public void setUp() { + cell = new TicTacToeCell(0, 0, 0); + } + + @Test + public void testInitialValues() { + Assertions.assertEquals(' ', cell.getMarker()); + Assertions.assertEquals(0, cell.getNum()); + Assertions.assertEquals(0, cell.getRow()); + Assertions.assertEquals(0, cell.getCol()); + } + + @Test + public void testSetMarker() { + cell.setMarker("X"); + assertEquals('X', cell.getMarker()); + assertFalse(cell.isEnabled()); + } + + @Test + public void testGetRow() { + assertEquals(0, cell.getRow()); + } + + @Test + public void testGetCol() { + assertEquals(0, cell.getCol()); + } + + @Test + public void testGetNum() { + assertEquals(0, cell.getNum()); + } +} diff --git a/src/test/java/org/example/AppTest.java b/src/test/java/org/example/AppTest.java new file mode 100644 index 0000000..d5f435d --- /dev/null +++ b/src/test/java/org/example/AppTest.java @@ -0,0 +1,38 @@ +package org.example; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} From fbab89e4b904ea1761bc8350990bd0a25db7af33 Mon Sep 17 00:00:00 2001 From: STELLSAN Date: Thu, 30 May 2024 22:56:03 +0300 Subject: [PATCH 2/2] empty_comm --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4de19fe..fb5af06 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ ## Задание №1 -В среде **Intellij Idea** создать проект **Maven** по шаблону **quickstart**. Убедиться в появлении веток `java/main` и `java/test` в разделе `src` проекта, а также файла с конфигурацией `pom.xml` в корне проекта. +В среде **Intellij Idea** создать проект **Maven** по шаблону **quickstart**. Убедиться в появлении веток `java/main` и `java/test` в разделе `src` проекта, а также файла с конфигурацией `pom.xml` в корне проекта. Добавить в проект код программы **Program.java**, содержащий реализацию игры "Крестики-Нолики" с использованием минимаксного алгоритма.