Jenkins
3 years ago
3 changed files with 633 additions and 0 deletions
-
21src/main/java/de/tims/viergewinnt/ai/GuiTest.java
-
264src/main/java/de/tims/viergewinnt/ai/Logic.java
-
348src/test/java/de/tims/viergewinnt/ai/LogicTest.java
@ -0,0 +1,21 @@ |
|||
package de.tims.viergewinnt.ai; |
|||
|
|||
import javax.swing.JFrame; |
|||
|
|||
public class GuiTest { |
|||
|
|||
JFrame frame; |
|||
public GuiTest() { |
|||
frame = new JFrame(); |
|||
frame.setSize(500, 500); |
|||
Logic logic = new Logic(6); |
|||
frame.add(logic.create4gewinntGui()); |
|||
frame.setVisible(true); |
|||
} |
|||
|
|||
public static void main(String[] args) { |
|||
// TODO Auto-generated method stub |
|||
GuiTest testGui = new GuiTest(); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,264 @@ |
|||
package de.tims.viergewinnt.ai; |
|||
|
|||
import java.awt.Color; |
|||
import java.awt.GridLayout; |
|||
import java.awt.event.ActionEvent; |
|||
import java.awt.event.ActionListener; |
|||
|
|||
import javax.swing.BorderFactory; |
|||
import javax.swing.BoxLayout; |
|||
import javax.swing.JButton; |
|||
import javax.swing.JLabel; |
|||
import javax.swing.JPanel; |
|||
|
|||
public class Logic { |
|||
|
|||
private int[][] board; |
|||
private int currentPlayer = 1; |
|||
private int player1Score = 0; |
|||
private int player2Score = 0; |
|||
|
|||
public Logic(int size) { |
|||
this.board = new int[size][size]; |
|||
this.buttons = new JButton[getBoardSize()]; |
|||
this.gamefield = new JLabel[getBoardSize() * getBoardSize()]; |
|||
} |
|||
|
|||
public void setField(int player, int row, int column) { |
|||
this.board[row][column] = player; |
|||
} |
|||
|
|||
public int getField(int row, int column) { |
|||
return this.board[row][column]; |
|||
} |
|||
|
|||
public void clearField() { |
|||
this.board = new int[getBoardSize()][getBoardSize()]; |
|||
} |
|||
|
|||
public int getBoardSize() { |
|||
return this.board.length; |
|||
} |
|||
|
|||
public void setCurrentPlayer(int player) { |
|||
this.currentPlayer = player; |
|||
} |
|||
|
|||
public int getCurrentPlayer() { |
|||
return this.currentPlayer; |
|||
} |
|||
|
|||
public void setPlayer1Score(int score) { |
|||
this.player1Score = score; |
|||
} |
|||
|
|||
public int getPlayer1Score() { |
|||
return this.player1Score; |
|||
} |
|||
|
|||
public void setPlayer2Score(int score) { |
|||
this.player2Score = score; |
|||
} |
|||
|
|||
public int getPlayer2Score() { |
|||
return this.player2Score; |
|||
} |
|||
|
|||
public int getFreePlace(int column) { |
|||
int size = getBoardSize() - 1; |
|||
while(getField(size, column) != 0) { |
|||
size--; |
|||
if(size < 0) { |
|||
return -1; |
|||
} |
|||
} |
|||
return size; |
|||
} |
|||
|
|||
public int playChip(int column) { |
|||
setField(getCurrentPlayer(), getFreePlace(column), column); |
|||
if(getFreePlace(column) == -1) { |
|||
buttons[column].setEnabled(false); |
|||
} |
|||
updateGui(); |
|||
if(testForWin()) { |
|||
gameover(); |
|||
} else if(!checkButtons()) { |
|||
gameover(); |
|||
} |
|||
setCurrentPlayer((getCurrentPlayer() % 2) + 1); |
|||
return 0; |
|||
} |
|||
|
|||
public boolean checkButtons() { |
|||
boolean res = false; |
|||
for(int i = 0; i < buttons.length; i++) { |
|||
res = buttons[i].isEnabled() | res; |
|||
} |
|||
return res; |
|||
} |
|||
|
|||
JPanel contentPanel; |
|||
JPanel buttonPanel; |
|||
JPanel playfieldPanel; |
|||
JButton[] buttons; |
|||
JLabel[] gamefield; |
|||
|
|||
public JPanel create4gewinntGui() { |
|||
contentPanel = new JPanel(); |
|||
contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.PAGE_AXIS)); |
|||
buttonPanel = new JPanel(new GridLayout(1, buttons.length)); |
|||
playfieldPanel = new JPanel(new GridLayout(buttons.length, buttons.length)); |
|||
contentPanel.add(buttonPanel); |
|||
contentPanel.add(playfieldPanel); |
|||
|
|||
for(int i = 0; i < buttons.length; i++) { |
|||
buttons[i] = new JButton(Integer.toString(i+1)); |
|||
buttons[i].addActionListener(new ButtonListener()); |
|||
buttonPanel.add(buttons[i]); |
|||
} |
|||
|
|||
for(int i = 0; i < gamefield.length; i++) { |
|||
gamefield[i] = new JLabel(); |
|||
gamefield[i].setBorder(BorderFactory.createLineBorder(Color.gray)); |
|||
gamefield[i].setOpaque(true); |
|||
gamefield[i].setBackground(Color.white); |
|||
playfieldPanel.add(gamefield[i]); |
|||
} |
|||
|
|||
return contentPanel; |
|||
} |
|||
|
|||
public void updateGui() { |
|||
for(int i = 0; i < board.length; i++) { |
|||
for(int j = 0; j < board[i].length; j++) { |
|||
if(getField(i,j) == 0) { |
|||
gamefield[j + getBoardSize() * i].setBackground(Color.white); |
|||
} else if(getField(i,j) == 1) { |
|||
gamefield[j + getBoardSize() * i].setBackground(Color.red); |
|||
} else { |
|||
gamefield[j + getBoardSize() * i].setBackground(Color.yellow); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
class ButtonListener implements ActionListener { |
|||
|
|||
@Override |
|||
public void actionPerformed(ActionEvent e) { |
|||
for(int i = 0; i < buttons.length; i++) { |
|||
if(e.getSource() == buttons[i]) { |
|||
playChip(i); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
public boolean testForWin() { |
|||
int player = getCurrentPlayer(); |
|||
int chain = 0; |
|||
for(int i = 0; i < board[0].length; i++) { |
|||
for(int j = 0; j < board.length; j++) { |
|||
if(getField(j,i) == player) { |
|||
chain++; |
|||
} else { |
|||
chain = 0; |
|||
} |
|||
if(chain == 4) return true; |
|||
} |
|||
} |
|||
chain = 0; |
|||
for(int i = 0; i < board.length; i++) { |
|||
for(int j = 0; j < board[0].length; j++) { |
|||
if(getField(i,j) == player) { |
|||
chain++; |
|||
} else { |
|||
chain = 0; |
|||
} |
|||
if(chain == 4) return true; |
|||
} |
|||
} |
|||
chain = 0; |
|||
for(int i = 0; i < board.length - 3; i++) { |
|||
for(int j = 0; j < board[i].length - 3; j++) { |
|||
if(getField(i,j) == player) { |
|||
chain++; |
|||
while(true) { |
|||
i++; j++; |
|||
if(getField(i,j) == player) { |
|||
chain++; |
|||
if(chain == 4) return true; |
|||
} else { |
|||
chain = 0; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
chain = 0; |
|||
for(int i = 0; i < board.length - 3; i++) { |
|||
for(int j = board[i].length - 1; j > 2; j--) { |
|||
if(getField(i,j) == player) { |
|||
chain++; |
|||
while(true) { |
|||
i++; j--; |
|||
if(getField(i,j) == player) { |
|||
chain++; |
|||
if(chain == 4) return true; |
|||
} else { |
|||
chain = 0; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
public int calcScore() { |
|||
int score = 1000; |
|||
for(int i = 0; i < board.length; i++) { |
|||
int oldScore = score; |
|||
for(int j = 0; j < board[i].length; j++) { |
|||
if(getField(i,j) != 0) { |
|||
score += 10; |
|||
} |
|||
} |
|||
if(score - (10 * board[0].length) == oldScore) { |
|||
score += (10 * board[0].length); |
|||
} |
|||
} |
|||
for(int i = 0; i < board[0].length; i++) { |
|||
for(int j = 0; j < board.length; j++) { |
|||
if(getField(j,i) == 0) { |
|||
break; |
|||
} |
|||
if(j == board.length - 1) { |
|||
score += (10 * board.length); |
|||
} |
|||
} |
|||
} |
|||
if(score == (1000 + 3 * (10 * board.length * board[0].length))) { |
|||
score += 500; |
|||
} |
|||
return score; |
|||
} |
|||
|
|||
public void gameover() { |
|||
if(getCurrentPlayer() == 1) { |
|||
setPlayer1Score(calcScore()); |
|||
} else { |
|||
setPlayer2Score(calcScore()); |
|||
} |
|||
clearField(); |
|||
for(int i = 0; i < getBoardSize(); i++) { |
|||
buttons[i].setEnabled(true); |
|||
} |
|||
updateGui(); |
|||
} |
|||
} |
@ -0,0 +1,348 @@ |
|||
package de.tims.viergewinnt.ai; |
|||
|
|||
import static org.junit.jupiter.api.Assertions.*; |
|||
|
|||
import java.util.stream.Stream; |
|||
|
|||
import org.junit.jupiter.api.BeforeEach; |
|||
import org.junit.jupiter.api.Test; |
|||
import org.junit.jupiter.params.ParameterizedTest; |
|||
import org.junit.jupiter.params.provider.Arguments; |
|||
import org.junit.jupiter.params.provider.MethodSource; |
|||
|
|||
class LogicTest { |
|||
|
|||
private Logic testObj; |
|||
|
|||
@BeforeEach |
|||
void setUp() throws Exception { |
|||
testObj = new Logic(6); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "[{index}] {0} Player {2} {3}") |
|||
@MethodSource("playfieldResults") |
|||
void testForWinTest(String testName, int[][] playfield, int player, boolean expectedResult) { |
|||
for(int i = 0; i < playfield.length; i++) { |
|||
for(int j = 0; j < playfield[i].length; j++) { |
|||
testObj.setField(playfield[i][j], i, j); |
|||
} |
|||
} |
|||
testObj.setCurrentPlayer(player); |
|||
|
|||
boolean realResult = testObj.testForWin(); |
|||
|
|||
assertEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@Test |
|||
void playChipTest() { |
|||
int column = 0; |
|||
int player = 1; |
|||
int expectedResult = 0; |
|||
testObj.create4gewinntGui(); |
|||
testObj.setCurrentPlayer(player); |
|||
|
|||
int realResult = testObj.playChip(column); |
|||
|
|||
assertEquals(expectedResult == realResult, 1 == testObj.getField(5, 0)); |
|||
} |
|||
|
|||
@Test |
|||
void changePlayerTo2Test() { |
|||
int column = 0; |
|||
int player = 1; |
|||
int expectedResult = 2; |
|||
testObj.create4gewinntGui(); |
|||
testObj.setCurrentPlayer(player); |
|||
testObj.playChip(column); |
|||
|
|||
int realResult = testObj.getCurrentPlayer(); |
|||
|
|||
assertEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@Test |
|||
void changePlayerTo1Test() { |
|||
int column = 0; |
|||
int player = 2; |
|||
int expectedResult = 1; |
|||
testObj.create4gewinntGui(); |
|||
testObj.setCurrentPlayer(player); |
|||
testObj.playChip(column); |
|||
|
|||
int realResult = testObj.getCurrentPlayer(); |
|||
|
|||
assertEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "[{index}] {0} with {1}") |
|||
@MethodSource("playfieldForScore") |
|||
void calcScoreTest(String testName, int[][] playfield, int expectedResult) { |
|||
for(int i = 0; i < playfield.length; i++) { |
|||
for(int j = 0; j < playfield[i].length; j++) { |
|||
testObj.setField(playfield[i][j], i, j); |
|||
} |
|||
} |
|||
|
|||
int realResult = testObj.calcScore(); |
|||
|
|||
assertEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@Test |
|||
void setFieldPlayer1Test() { |
|||
int player = 1; |
|||
int row = 0; |
|||
int column = 0; |
|||
|
|||
testObj.setField(player, row, column); |
|||
|
|||
assertEquals(1, testObj.getField(row, column)); |
|||
} |
|||
|
|||
@Test |
|||
void setFieldPlayer2Test() { |
|||
int player = 2; |
|||
int row = 0; |
|||
int column = 0; |
|||
|
|||
testObj.setField(player, row, column); |
|||
|
|||
assertEquals(player, testObj.getField(row, column)); |
|||
} |
|||
|
|||
@Test |
|||
void getFieldTest() { |
|||
int player = 2; |
|||
int row = 0; |
|||
int column = 0; |
|||
|
|||
testObj.setField(player, row, column); |
|||
int realResult = testObj.getField(row, column); |
|||
|
|||
assertEquals(player, realResult); |
|||
} |
|||
|
|||
@Test |
|||
void setCurrentPlayerTest() { |
|||
int player = 2; |
|||
|
|||
testObj.setCurrentPlayer(player); |
|||
|
|||
assertEquals(player, testObj.getCurrentPlayer()); |
|||
} |
|||
|
|||
@Test |
|||
void getCurrentPlayerTest() { |
|||
int player = 2; |
|||
|
|||
testObj.setCurrentPlayer(player); |
|||
int realResult = testObj.getCurrentPlayer(); |
|||
|
|||
assertEquals(player, realResult); |
|||
} |
|||
|
|||
@Test |
|||
void setPlayer1ScoreTest() { |
|||
int expectedResult = 500; |
|||
testObj.setPlayer1Score(expectedResult); |
|||
|
|||
assertEquals(expectedResult, testObj.getPlayer1Score()); |
|||
} |
|||
|
|||
@Test |
|||
void getPlayer1ScoreTest() { |
|||
int expectedResult = 500; |
|||
testObj.setPlayer1Score(expectedResult); |
|||
|
|||
int realResult = testObj.getPlayer1Score(); |
|||
|
|||
assertEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@Test |
|||
void createGameLogicTest() { |
|||
int size = 6; |
|||
Logic expectedResult = testObj; |
|||
Logic realResult = new Logic(size); |
|||
|
|||
assertEquals(expectedResult.getClass(), realResult.getClass()); |
|||
} |
|||
|
|||
@ParameterizedTest(name = "[{index}] {0}") |
|||
@MethodSource("boardSizeParameters") |
|||
void getBoardSizeTest(String testName, int size) { |
|||
int expectedResult = size; |
|||
int realResult = new Logic(size).getBoardSize(); |
|||
|
|||
assertEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@Test |
|||
void gameoverTest() { |
|||
testObj.setField(1, 0, 0); |
|||
testObj.create4gewinntGui(); |
|||
|
|||
testObj.gameover(); |
|||
|
|||
assertEquals(1010 == testObj.getPlayer1Score(), 0 == testObj.getField(0,0)); |
|||
} |
|||
|
|||
@Test |
|||
void clearFieldTest() { |
|||
testObj.setField(1, 0, 0); |
|||
|
|||
testObj.clearField(); |
|||
|
|||
assertEquals(0, testObj.getField(0, 0)); |
|||
} |
|||
|
|||
@Test |
|||
void clearFieldTestCompleteClear() { |
|||
testObj.setField(1, 5, 5); |
|||
|
|||
testObj.clearField(); |
|||
|
|||
assertEquals(0, testObj.getField(5, 5)); |
|||
} |
|||
|
|||
@Test |
|||
void getFreePlaceTestWithEmptyField() { |
|||
assertEquals(testObj.getBoardSize() - 1, testObj.getFreePlace(0)); |
|||
} |
|||
|
|||
@Test |
|||
void getFreePlaceTestWithFilledField() { |
|||
testObj.setField(1, testObj.getBoardSize() - 1, 0); |
|||
|
|||
assertEquals(testObj.getBoardSize() - 2, testObj.getFreePlace(0)); |
|||
} |
|||
|
|||
@Test |
|||
void getFreePlaceTestWithAnyField() { |
|||
testObj.setField(1, testObj.getBoardSize() - 1, 0); |
|||
testObj.setField(1, testObj.getBoardSize() - 2, 0); |
|||
|
|||
assertEquals(testObj.getBoardSize() - 3, testObj.getFreePlace(0)); |
|||
} |
|||
|
|||
@Test |
|||
void checkButtonsTestTrue() { |
|||
testObj.create4gewinntGui(); |
|||
boolean expectedResult = true; |
|||
|
|||
boolean realResult = testObj.checkButtons(); |
|||
|
|||
assertEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
@Test |
|||
void checkButtonsTestFalse() { |
|||
testObj.create4gewinntGui(); |
|||
boolean expectedResult = false; |
|||
for(int i = 0; i < testObj.buttons.length; i++) { |
|||
testObj.buttons[i].setEnabled(false); |
|||
} |
|||
|
|||
boolean realResult = testObj.checkButtons(); |
|||
|
|||
assertEquals(expectedResult, realResult); |
|||
} |
|||
|
|||
private static Stream<Arguments> playfieldResults() { |
|||
int[][] playfield1 = {{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 0, 0, 0, 0}, |
|||
{1, 0, 0, 0, 0, 0}, |
|||
{1, 0, 0, 0, 0, 0}, |
|||
{1, 0, 0, 0, 0, 0}, |
|||
{1, 0, 0, 0, 0, 0}}; |
|||
int[][] playfield2 = {{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 0, 1, 0, 0}, |
|||
{0, 0, 0, 1, 0, 0}, |
|||
{0, 0, 0, 1, 0, 0}, |
|||
{0, 0, 0, 1, 0, 0}}; |
|||
int[][] playfield3 = {{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 0, 0, 0, 0}, |
|||
{1, 1, 1, 1, 0, 0}}; |
|||
int[][] playfield4 = {{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 0, 0, 0, 0}, |
|||
{1, 0, 0, 0, 0, 0}, |
|||
{1, 1, 0, 0, 0, 0}, |
|||
{2, 2, 1, 0, 0, 0}, |
|||
{2, 2, 2, 1, 0, 0}}; |
|||
int[][] playfield5 = {{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 0, 0, 0, 1}, |
|||
{0, 0, 0, 0, 1, 2}, |
|||
{0, 0, 0, 1, 2, 2}, |
|||
{0, 0, 1, 1, 2, 2}}; |
|||
return Stream.of( |
|||
Arguments.of("emptyField", new int[6][6], 1, false), |
|||
Arguments.of("4 in column1 player1", playfield1, 1, true), |
|||
Arguments.of("4 in a column player1", playfield2, 1, true), |
|||
Arguments.of("4 in a row player1", playfield3, 1, true), |
|||
Arguments.of("4 diagonal right player1", playfield4, 1, true), |
|||
Arguments.of("4 diagonal left player1", playfield5, 1, true) |
|||
); |
|||
} |
|||
|
|||
private static Stream<Arguments> playfieldForScore() { |
|||
int[][] playfield1 = {{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 1, 2, 0, 0}, |
|||
{0, 0, 1, 2, 0, 0}, |
|||
{0, 0, 1, 2, 0, 0}, |
|||
{0, 0, 1, 1, 2, 0}}; |
|||
int[][] playfield2 = {{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 0, 0, 0, 0}, |
|||
{1, 1, 1, 2, 2, 2}}; |
|||
int[][] playfield3 = {{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 0, 0, 0, 0}, |
|||
{1, 1, 2, 2, 1, 2}, |
|||
{0, 0, 0, 0, 0, 0}, |
|||
{0, 0, 0, 0, 0, 0}, |
|||
{1, 1, 1, 2, 2, 2}}; |
|||
int[][] playfield4 = {{2, 0, 0, 0, 0, 0}, |
|||
{2, 0, 0, 0, 0, 0}, |
|||
{1, 0, 0, 0, 0, 0}, |
|||
{2, 0, 0, 0, 0, 0}, |
|||
{1, 0, 0, 0, 0, 0}, |
|||
{1, 0, 0, 0, 0, 0}}; |
|||
int[][] playfield5 = {{2, 0, 1, 0, 0, 0}, |
|||
{2, 0, 1, 0, 0, 0}, |
|||
{1, 0, 2, 0, 0, 0}, |
|||
{2, 0, 2, 0, 0, 0}, |
|||
{1, 0, 2, 0, 0, 0}, |
|||
{1, 0, 1, 0, 0, 0}}; |
|||
int[][] playfield6 = {{1, 1, 1, 1, 2, 2}, |
|||
{2, 1, 1, 1, 1, 2}, |
|||
{2, 1, 1, 2, 1, 2}, |
|||
{2, 1, 1, 2, 1, 2}, |
|||
{2, 1, 2, 2, 1, 2}, |
|||
{2, 1, 2, 2, 1, 2}}; |
|||
return Stream.of( |
|||
Arguments.of("emptyField", new int[6][6], 1000), |
|||
Arguments.of("9 chips played", playfield1, 1090), |
|||
Arguments.of("first row filled", playfield2, 1120), |
|||
Arguments.of("2 rows filled", playfield3, 1240), |
|||
Arguments.of("first column filled", playfield4, 1120), |
|||
Arguments.of("2 column filled", playfield5, 1240), |
|||
Arguments.of("fullyFilled", playfield6, 2580) |
|||
); |
|||
} |
|||
|
|||
private static Stream<Arguments> boardSizeParameters() { |
|||
return Stream.of( |
|||
Arguments.of("board with size 0", 0), |
|||
Arguments.of("board with size 6", 6) |
|||
); |
|||
} |
|||
|
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue