[TASK] Import.
This commit is contained in:
commit
43e236fda9
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||||
|
<classpathentry kind="lib" path="forms-1.3.0.jar" sourcepath="forms-1.3.0-src.zip"/>
|
||||||
|
<classpathentry kind="lib" path="miglayout15-swing.jar" sourcepath="miglayout-src.zip"/>
|
||||||
|
<classpathentry kind="output" path="bin"/>
|
||||||
|
</classpath>
|
|
@ -0,0 +1,2 @@
|
||||||
|
*.class
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>TicTacToe</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
|
@ -0,0 +1,12 @@
|
||||||
|
#Sat Sep 03 13:48:41 CEST 2011
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||||
|
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.source=1.6
|
|
@ -0,0 +1,3 @@
|
||||||
|
Manifest-Version: 1.0
|
||||||
|
Class-Path: tictactoe.jar
|
||||||
|
Main-Class: org.jpt.tictactoe.Game
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
|
||||||
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||||
|
<listEntry value="/TicTacToe/src/org/jpt/tictactoe/gui/Main.java"/>
|
||||||
|
</listAttribute>
|
||||||
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||||
|
<listEntry value="1"/>
|
||||||
|
</listAttribute>
|
||||||
|
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||||
|
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||||
|
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||||
|
</listAttribute>
|
||||||
|
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.jpt.tictactoe.gui.Main"/>
|
||||||
|
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="TicTacToe"/>
|
||||||
|
</launchConfiguration>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,33 @@
|
||||||
|
package org.jpt.tictactoe;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public abstract class AbstractKi extends AbstractPlayer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
public AbstractKi(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Game
|
||||||
|
*/
|
||||||
|
public abstract boolean takeTurn(Game game);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fieldSet
|
||||||
|
* @return ArrayList<int[]>
|
||||||
|
*/
|
||||||
|
protected ArrayList<int[]> getEmptyFieldsFromFieldSet(int[][] fields) {
|
||||||
|
ArrayList<int[]> emptyFields = new ArrayList<int[]> ();
|
||||||
|
for(int x = 0; x < 3; x++){
|
||||||
|
for(int y = 0; y < 3; y++){
|
||||||
|
if(fields[x][y] == 0) emptyFields.add(new int[]{x,y});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return emptyFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
package org.jpt.tictactoe;
|
||||||
|
|
||||||
|
public abstract class AbstractPlayer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* contains the next turn of the human player
|
||||||
|
* @var int[]
|
||||||
|
*/
|
||||||
|
protected int[] nextField = new int[2];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var String
|
||||||
|
*/
|
||||||
|
protected String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected int playerNumber;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
* @param playerNumber
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
public AbstractPlayer(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param playerNumber
|
||||||
|
*/
|
||||||
|
public void setPlayerNumber(int playerNumber) {
|
||||||
|
this.playerNumber = playerNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public int getPlayerNumber() {
|
||||||
|
return this.playerNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will be called by stuff.
|
||||||
|
* It will call a similar method on the game - this is legit.
|
||||||
|
*/
|
||||||
|
abstract public boolean takeTurn(Game game);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the next field the player can use to make a turn.
|
||||||
|
* This is in use for HumanPlayers only!
|
||||||
|
* @param nextField
|
||||||
|
*/
|
||||||
|
public void setNextTurn(int[] nextField) {
|
||||||
|
this.nextField = nextField;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package org.jpt.tictactoe;
|
||||||
|
|
||||||
|
public interface AbstractView {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FieldSet fieldSet
|
||||||
|
* draws the field - however this will happen
|
||||||
|
*/
|
||||||
|
public abstract void drawField(FieldSet fieldSet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param player
|
||||||
|
* @return int[] containing the coordinates
|
||||||
|
*/
|
||||||
|
public abstract int[] askPlayerForField();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param player
|
||||||
|
* @return String the Name
|
||||||
|
*/
|
||||||
|
public abstract String askPlayerForName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* have the view display the given message.
|
||||||
|
* @param msg
|
||||||
|
*/
|
||||||
|
public abstract void message(String msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* I need this for gui stuff. Sorry :(
|
||||||
|
* @param game
|
||||||
|
*/
|
||||||
|
public abstract void setGame(Game game);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package org.jpt.tictactoe;
|
||||||
|
|
||||||
|
public class DumbKi extends AbstractKi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
public DumbKi(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Game game
|
||||||
|
*/
|
||||||
|
public boolean takeTurn(Game game) {
|
||||||
|
for(int i = 0; i<3; i++) {
|
||||||
|
for(int j = 0; j<3; j++) {
|
||||||
|
if(game.setFieldOnFieldSet(i, j, this)) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package org.jpt.tictactoe;
|
||||||
|
|
||||||
|
public class FieldSet {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2D-Array for the field
|
||||||
|
*/
|
||||||
|
protected int[][] fields = new int[3][3];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Field constructor.
|
||||||
|
* Initializes field.
|
||||||
|
*/
|
||||||
|
public FieldSet(){
|
||||||
|
for(int i = 0; i<3; i++) {
|
||||||
|
for(int j = 0; j<3; j++) {
|
||||||
|
fields[i][j] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* method to set a certain field to n.
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @param n
|
||||||
|
* @throws UsedFieldException
|
||||||
|
*/
|
||||||
|
public void setField(int x, int y, int n) throws UsedFieldException {
|
||||||
|
if(this.fields[x][y] != 0) throw new UsedFieldException();
|
||||||
|
else this.fields[x][y] = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* method to retrieve the value of a certain field.
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public int getField(int x, int y) {
|
||||||
|
return this.fields[x][y];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the whole fieldset
|
||||||
|
* @return int[][]
|
||||||
|
*/
|
||||||
|
public int[][] getFieldSet() {
|
||||||
|
return this.fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the fieldset.
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean isFull() {
|
||||||
|
for(int i = 0; i<3; i++) {
|
||||||
|
for(int j = 0; j<3; j++) {
|
||||||
|
if(fields[i][j] == 0) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,264 @@
|
||||||
|
package org.jpt.tictactoe;
|
||||||
|
|
||||||
|
public class Game {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var FieldSet
|
||||||
|
*/
|
||||||
|
protected FieldSet fieldSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Index that points to the active player in the players-array
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected int activePlayer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
protected boolean gameOver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Array
|
||||||
|
*/
|
||||||
|
protected AbstractPlayer[] players = new AbstractPlayer[2];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected int playerCount = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var AbstractView
|
||||||
|
*/
|
||||||
|
protected AbstractView view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author JPT
|
||||||
|
* Contains representative values for the different kinds of players this game supports.
|
||||||
|
*/
|
||||||
|
public enum PlayerType {
|
||||||
|
HumanPlayer, DumbKI, MediumKI, RandomKI
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
*/
|
||||||
|
public Game() {
|
||||||
|
this.resetGame();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this method will process almost everything as long as there is no human interaction needed.
|
||||||
|
* also, it does NOT process human player turns. they do it on their own.
|
||||||
|
*/
|
||||||
|
public void processGame() {
|
||||||
|
this.gameOver = this.checkGameOver();
|
||||||
|
if(this.isGameOver() == true) return;
|
||||||
|
//get active player
|
||||||
|
AbstractPlayer activePlayer = this.getActivePlayer();
|
||||||
|
//as long as active player is NOT human, do it automatically
|
||||||
|
while(activePlayer instanceof HumanPlayer == false) {
|
||||||
|
activePlayer.takeTurn(this);
|
||||||
|
this.gameOver = this.checkGameOver();
|
||||||
|
this.drawField();
|
||||||
|
activePlayer = this.getActivePlayer();
|
||||||
|
|
||||||
|
//it's not thaat important...
|
||||||
|
if(this.isGameOver()) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a player to the game. hehehehe... the game...
|
||||||
|
* you just lost it. :P
|
||||||
|
* @param player
|
||||||
|
*/
|
||||||
|
public void addPlayer(AbstractPlayer player) {
|
||||||
|
player.setPlayerNumber(this.playerCount + 1);
|
||||||
|
this.players[this.playerCount] = player;
|
||||||
|
this.playerCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks the field for a gameover condition.
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
protected boolean checkGameOver() {
|
||||||
|
int[][] fieldSetCopy = this.fieldSet.getFieldSet();
|
||||||
|
int winnerId = 0;
|
||||||
|
|
||||||
|
//check rows
|
||||||
|
for(int x = 0; x < 3; x++) {
|
||||||
|
if(fieldSetCopy[x][0] == fieldSetCopy[x][1] && fieldSetCopy[x][1] == fieldSetCopy[x][2]) {
|
||||||
|
if(winnerId == 0) winnerId = fieldSetCopy[x][0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//check cols
|
||||||
|
for(int y = 0; y < 3; y++) {
|
||||||
|
if(fieldSetCopy[0][y] == fieldSetCopy[1][y] && fieldSetCopy[1][y] == fieldSetCopy[2][y]) {
|
||||||
|
if(winnerId == 0) winnerId = fieldSetCopy[0][y];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//check diags
|
||||||
|
if(fieldSetCopy[0][0] == fieldSetCopy[1][1] && fieldSetCopy[1][1] == fieldSetCopy[2][2]) {
|
||||||
|
if(winnerId == 0) winnerId = fieldSetCopy[1][1];
|
||||||
|
}
|
||||||
|
|
||||||
|
//other diags
|
||||||
|
if(fieldSetCopy[2][0] == fieldSetCopy[1][1] && fieldSetCopy[1][1] == fieldSetCopy[0][2]) {
|
||||||
|
if(winnerId == 0) winnerId = fieldSetCopy[1][1];
|
||||||
|
}
|
||||||
|
|
||||||
|
//if winner, announce winner
|
||||||
|
if(winnerId != 0) {
|
||||||
|
this.view.message(this.getPlayerByPlayerNumber(winnerId).getName() + " won the game!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//else, if it's just full...
|
||||||
|
if(this.fieldSet.isFull() == true){
|
||||||
|
this.view.message("Apparently, this is a draw. Congratulations :D");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the player is allowed to take its turn.
|
||||||
|
* Also manages the activePlayer attribute.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @param player
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean setFieldOnFieldSet(int x, int y, AbstractPlayer player) {
|
||||||
|
if(player != this.getActivePlayer()) {
|
||||||
|
this.view.message(player.getName() + " took an illegal turn!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
//check whether coords are in range...
|
||||||
|
if(x < 0 || x > 2 || y < 0 || y > 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.fieldSet.setField(x, y, player.getPlayerNumber());
|
||||||
|
this.view.message(player.getName() + " took his turn and marked on: ["+x+","+y+"]");
|
||||||
|
this.changeActivePlayer();
|
||||||
|
return true;
|
||||||
|
} catch (UsedFieldException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* changes the active player.
|
||||||
|
*/
|
||||||
|
protected void changeActivePlayer() {
|
||||||
|
int activePlayerPointer = this.activePlayer;
|
||||||
|
activePlayerPointer++;
|
||||||
|
if(activePlayerPointer == this.players.length) activePlayerPointer = 0;
|
||||||
|
this.activePlayer = activePlayerPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return AbstractPlayer active player
|
||||||
|
*/
|
||||||
|
public AbstractPlayer getActivePlayer() {
|
||||||
|
return this.players[this.activePlayer];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return AbstractPlayer player
|
||||||
|
*/
|
||||||
|
protected AbstractPlayer getPlayerByPlayerNumber(int playerNumber) {
|
||||||
|
for(int i = 0; i < this.players.length; i++) {
|
||||||
|
if(this.players[i].getPlayerNumber() == playerNumber) return this.players[i];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return FieldSet
|
||||||
|
*/
|
||||||
|
public FieldSet getFieldSet() {
|
||||||
|
return this.fieldSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the view.
|
||||||
|
* @param view
|
||||||
|
*/
|
||||||
|
public void setView(AbstractView view) {
|
||||||
|
view.message("Welcome to TicTacToe!");
|
||||||
|
this.view = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the view.
|
||||||
|
* @return AbstractView view
|
||||||
|
*/
|
||||||
|
public AbstractView getView() {
|
||||||
|
return this.view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean isGameOver() {
|
||||||
|
return this.gameOver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Have the view draw the field.
|
||||||
|
*/
|
||||||
|
public void drawField() {
|
||||||
|
this.view.drawField(this.fieldSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a player based on a given PlayerType
|
||||||
|
* @param playerType
|
||||||
|
* @param name
|
||||||
|
* @return AbstractPlayer
|
||||||
|
*/
|
||||||
|
public AbstractPlayer createPlayerByEnum(PlayerType playerType, String name) {
|
||||||
|
switch(playerType) {
|
||||||
|
case HumanPlayer:
|
||||||
|
return new HumanPlayer(name);
|
||||||
|
case DumbKI:
|
||||||
|
return new DumbKi(name);
|
||||||
|
case MediumKI:
|
||||||
|
return new MediumKi(name);
|
||||||
|
case RandomKI:
|
||||||
|
return new RandomKi(name);
|
||||||
|
default:
|
||||||
|
System.out.println("Not implemented yet: " + playerType);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resets all game relevant variables except for the players.
|
||||||
|
*/
|
||||||
|
public void resetGame() {
|
||||||
|
this.fieldSet = new FieldSet();
|
||||||
|
this.gameOver = false;
|
||||||
|
this.playerCount = 0;
|
||||||
|
this.activePlayer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return AbstractPlayer[]
|
||||||
|
*/
|
||||||
|
public AbstractPlayer[] getPlayers() {
|
||||||
|
return this.players;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package org.jpt.tictactoe;
|
||||||
|
|
||||||
|
public class HumanPlayer extends AbstractPlayer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
public HumanPlayer(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the next turn the humanPlayer will do.
|
||||||
|
* @param nextField
|
||||||
|
*/
|
||||||
|
public void setNextTurn(int[] nextField) {
|
||||||
|
this.nextField = nextField;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We take our turn here.
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean takeTurn(Game game) {
|
||||||
|
if(game.isGameOver()) return false;
|
||||||
|
boolean success = false;
|
||||||
|
int[] coordinates = this.nextField;
|
||||||
|
if(coordinates == null) {
|
||||||
|
game.getView().message("Ups.");
|
||||||
|
}
|
||||||
|
int x = coordinates[0];
|
||||||
|
int y = coordinates[1];
|
||||||
|
|
||||||
|
success = game.setFieldOnFieldSet(x, y, this);
|
||||||
|
if(!success) {
|
||||||
|
game.getView().message("The field on ["+x+","+y+"] is already taken or invalid.");
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
package org.jpt.tictactoe;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class MediumKi extends AbstractKi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
public MediumKi(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Game game
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean takeTurn(Game game) {
|
||||||
|
Random randomGenerator = new Random(System.nanoTime());
|
||||||
|
int[][] fields = game.getFieldSet().getFieldSet();
|
||||||
|
AbstractPlayer[] players = game.getPlayers();
|
||||||
|
int enemyNumber = 0;
|
||||||
|
for(int i = 0; i < players.length; i++) {
|
||||||
|
if(players[i].equals(this) == false) enemyNumber = players[i].getPlayerNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<int[]> instantWinFields = this.getWinFieldsForNumber(this.getPlayerNumber(), fields, false);
|
||||||
|
if(instantWinFields.size() > 0) {
|
||||||
|
int randomInt = (instantWinFields.size() > 1) ? randomGenerator.nextInt(instantWinFields.size()) : 0;
|
||||||
|
int[] coord = instantWinFields.get(randomInt);
|
||||||
|
int x = coord[0];
|
||||||
|
int y = coord[1];
|
||||||
|
if(game.setFieldOnFieldSet(x, y, this)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<int[]> enemyFields = this.getWinFieldsForNumber(enemyNumber, fields, false);
|
||||||
|
if(enemyFields.size() > 0) {
|
||||||
|
int randomInt = (enemyFields.size() > 1) ? randomGenerator.nextInt(enemyFields.size() - 1) : 0;
|
||||||
|
int[] coord = enemyFields.get(randomInt);
|
||||||
|
int x = coord[0];
|
||||||
|
int y = coord[1];
|
||||||
|
if(game.setFieldOnFieldSet(x, y, this)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<int[]> possibleWinFields = this.getWinFieldsForNumber(this.getPlayerNumber(), fields, true);
|
||||||
|
if(possibleWinFields.size() > 0) {
|
||||||
|
int randomInt = (possibleWinFields.size() > 1) ? randomGenerator.nextInt(possibleWinFields.size()) : 0;
|
||||||
|
int[] coord = possibleWinFields.get(randomInt);
|
||||||
|
int x = coord[0];
|
||||||
|
int y = coord[1];
|
||||||
|
if(game.setFieldOnFieldSet(x, y, this)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<int[]> emptyFields = this.getEmptyFieldsFromFieldSet(fields);
|
||||||
|
if(emptyFields.size() > 0) {
|
||||||
|
int randomInt = (emptyFields.size() > 1) ? randomGenerator.nextInt(emptyFields.size() - 1) : 0;
|
||||||
|
int[] coord = emptyFields.get(randomInt);
|
||||||
|
int x = coord[0];
|
||||||
|
int y = coord[1];
|
||||||
|
if(game.setFieldOnFieldSet(x, y, this)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
game.getView().message("I don't know what to do! O__o");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the position of the empty field in case the the other two fields are equal
|
||||||
|
* @param int[] numbers
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
protected int getFreeFieldFor(int[] numbers, int playerNumber, boolean softResults) {
|
||||||
|
if(numbers[0] == numbers[1] || numbers[1] == numbers[2] || numbers[2] == numbers[0]) {
|
||||||
|
int[] counter = new int[]{0,0,0};
|
||||||
|
int fieldPos = 0;
|
||||||
|
for(int i = 0; i < 3; i++) {
|
||||||
|
if(numbers[i] == 0) fieldPos = i;
|
||||||
|
counter[numbers[i]]++;
|
||||||
|
}
|
||||||
|
if(counter[0] == 1 && counter[playerNumber] == 2) return fieldPos;
|
||||||
|
if(softResults == true && counter[0] == 2 && counter[playerNumber] == 1) return fieldPos;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns an ArrayList of possible winner-coords based on the game logic for the given playerNumber.
|
||||||
|
* [we search for a win condition and then add empty fields]
|
||||||
|
* @return ArrayList<int[]>
|
||||||
|
*/
|
||||||
|
protected ArrayList<int[]> getWinFieldsForNumber(int playerNumber, int[][] fields, boolean softResult) {
|
||||||
|
ArrayList<int[]> relevantFields = new ArrayList<int[]> ();
|
||||||
|
int fieldPos;
|
||||||
|
|
||||||
|
//check rows
|
||||||
|
for(int x = 0; x < 3; x++) {
|
||||||
|
fieldPos = this.getFreeFieldFor(new int[]{fields[x][0],fields[x][1],fields[x][2]}, playerNumber, softResult);
|
||||||
|
if(fieldPos > -1) relevantFields.add(new int[]{x,fieldPos});
|
||||||
|
}
|
||||||
|
|
||||||
|
//check cols
|
||||||
|
for(int y = 0; y < 3; y++) {
|
||||||
|
fieldPos = this.getFreeFieldFor(new int[]{fields[0][y],fields[1][y],fields[2][y]}, playerNumber, softResult);
|
||||||
|
if(fieldPos > -1) relevantFields.add(new int[]{fieldPos, y});
|
||||||
|
}
|
||||||
|
|
||||||
|
//check diags
|
||||||
|
fieldPos = this.getFreeFieldFor(new int[]{fields[0][0],fields[1][1],fields[2][2]}, playerNumber, softResult);
|
||||||
|
if(fieldPos > -1) relevantFields.add(new int[]{fieldPos, fieldPos});
|
||||||
|
|
||||||
|
//check diags
|
||||||
|
fieldPos = this.getFreeFieldFor(new int[]{fields[2][0],fields[1][1],fields[0][2]}, playerNumber, softResult);
|
||||||
|
if(fieldPos > -1) relevantFields.add(new int[]{2 - fieldPos, fieldPos});
|
||||||
|
|
||||||
|
return relevantFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package org.jpt.tictactoe;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class RandomKi extends AbstractKi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
public RandomKi(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Game game
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean takeTurn(Game game) {
|
||||||
|
Random randomGenerator = new Random(System.nanoTime());
|
||||||
|
int[][] fields = game.getFieldSet().getFieldSet();
|
||||||
|
ArrayList<int[]> emptyFields = this.getEmptyFieldsFromFieldSet(fields);
|
||||||
|
int i = emptyFields.size();
|
||||||
|
i = (i > 1) ? i - 1 : i;
|
||||||
|
int randomInt = randomGenerator.nextInt(i);
|
||||||
|
int[] coord = emptyFields.get(randomInt);
|
||||||
|
int x = coord[0];
|
||||||
|
int y = coord[1];
|
||||||
|
|
||||||
|
if(game.setFieldOnFieldSet(x, y, this)) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package org.jpt.tictactoe;
|
||||||
|
|
||||||
|
public class UsedFieldException extends Exception {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,401 @@
|
||||||
|
package org.jpt.tictactoe.gui;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.ComponentOrientation;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseListener;
|
||||||
|
|
||||||
|
import javax.swing.BoxLayout;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTextArea;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
import javax.swing.text.BadLocationException;
|
||||||
|
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
|
||||||
|
import org.jpt.tictactoe.AbstractView;
|
||||||
|
import org.jpt.tictactoe.FieldSet;
|
||||||
|
import org.jpt.tictactoe.Game;
|
||||||
|
|
||||||
|
import com.jgoodies.forms.factories.FormFactory;
|
||||||
|
import com.jgoodies.forms.layout.ColumnSpec;
|
||||||
|
import com.jgoodies.forms.layout.FormLayout;
|
||||||
|
import com.jgoodies.forms.layout.RowSpec;
|
||||||
|
|
||||||
|
public class GuiView extends JFrame implements AbstractView, ActionListener, MouseListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var JLabel
|
||||||
|
*/
|
||||||
|
public JLabel player1NameLabel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var JLabel
|
||||||
|
*/
|
||||||
|
public JLabel player2NameLabel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* an array of buttons...
|
||||||
|
*/
|
||||||
|
protected JButton[][] buttons = new JButton[3][3];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var JTextArea
|
||||||
|
*/
|
||||||
|
protected JTextArea textArea;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var NewGameDialog
|
||||||
|
*/
|
||||||
|
protected NewGameDialog newGameDialog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains the game. I need this to be consistent here.
|
||||||
|
* It's important for the Gui stuff.
|
||||||
|
* @var Game
|
||||||
|
*/
|
||||||
|
protected Game game;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var JScrollPane
|
||||||
|
*/
|
||||||
|
protected JScrollPane scrollPane;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var JButton
|
||||||
|
*/
|
||||||
|
protected JButton newGameButton;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var JButton
|
||||||
|
*/
|
||||||
|
protected JButton repeatGameButton;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param game
|
||||||
|
*/
|
||||||
|
public void setGame(Game game) {
|
||||||
|
this.game = game;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the frame.
|
||||||
|
* And the stuff within.
|
||||||
|
* And even more weird configurations.
|
||||||
|
*/
|
||||||
|
public GuiView() {
|
||||||
|
setTitle("TicTacToe");
|
||||||
|
setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
|
||||||
|
getContentPane().setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
|
||||||
|
getContentPane().setLayout(new BorderLayout(0, 0));
|
||||||
|
|
||||||
|
JPanel MidWestPanel = new JPanel();
|
||||||
|
MidWestPanel.setPreferredSize(new Dimension(135, 10));
|
||||||
|
MidWestPanel.setMinimumSize(new Dimension(125, 10));
|
||||||
|
getContentPane().add(MidWestPanel, BorderLayout.WEST);
|
||||||
|
MidWestPanel.setLayout(new FormLayout(new ColumnSpec[] {
|
||||||
|
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
|
||||||
|
ColumnSpec.decode("125px"),},
|
||||||
|
new RowSpec[] {
|
||||||
|
FormFactory.LINE_GAP_ROWSPEC,
|
||||||
|
RowSpec.decode("23px"),
|
||||||
|
FormFactory.LINE_GAP_ROWSPEC,
|
||||||
|
RowSpec.decode("23px"),}));
|
||||||
|
|
||||||
|
JLabel player1Label = new JLabel("Spieler 1");
|
||||||
|
player1Label.setFont(new Font("SansSerif", Font.BOLD, 12));
|
||||||
|
MidWestPanel.add(player1Label, "2, 2, center, center");
|
||||||
|
|
||||||
|
JLabel player1NameLabel = new JLabel("");
|
||||||
|
this.player1NameLabel = player1NameLabel;
|
||||||
|
MidWestPanel.add(player1NameLabel, "2, 4, center, center");
|
||||||
|
|
||||||
|
JPanel MidEastPanel = new JPanel();
|
||||||
|
MidEastPanel.setPreferredSize(new Dimension(135, 10));
|
||||||
|
MidEastPanel.setMinimumSize(new Dimension(100, 10));
|
||||||
|
getContentPane().add(MidEastPanel, BorderLayout.EAST);
|
||||||
|
MidEastPanel.setLayout(new FormLayout(new ColumnSpec[] {
|
||||||
|
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
|
||||||
|
ColumnSpec.decode("125px"),},
|
||||||
|
new RowSpec[] {
|
||||||
|
FormFactory.LINE_GAP_ROWSPEC,
|
||||||
|
RowSpec.decode("23px"),
|
||||||
|
FormFactory.LINE_GAP_ROWSPEC,
|
||||||
|
RowSpec.decode("23px"),}));;
|
||||||
|
|
||||||
|
JLabel player2Label = new JLabel("Spieler 2");
|
||||||
|
player2Label.setFont(new Font("SansSerif", Font.BOLD, 12));
|
||||||
|
MidEastPanel.add(player2Label, "2, 2, center, center");
|
||||||
|
|
||||||
|
JLabel player2NameLabel = new JLabel("");
|
||||||
|
this.player2NameLabel = player2NameLabel;
|
||||||
|
MidEastPanel.add(player2NameLabel, "2, 4, center, center");
|
||||||
|
|
||||||
|
JPanel TitlePanel = new JPanel();
|
||||||
|
getContentPane().add(TitlePanel, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
JLabel TitleLabel = new JLabel("TicTacToe - Die Maschine gewinnt immer!");
|
||||||
|
TitleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||||
|
TitlePanel.add(TitleLabel);
|
||||||
|
TitleLabel.setFont(new Font("Tahoma", Font.BOLD, 14));
|
||||||
|
TitleLabel.setHorizontalTextPosition(SwingConstants.CENTER);
|
||||||
|
|
||||||
|
JPanel TextPanel = new JPanel();
|
||||||
|
TextPanel.setBounds(new Rectangle(50, 50, 0, 150));
|
||||||
|
getContentPane().add(TextPanel, BorderLayout.SOUTH);
|
||||||
|
|
||||||
|
JTextArea textArea = new JTextArea(7,46);
|
||||||
|
textArea.setLineWrap(true);
|
||||||
|
textArea.setEditable(false);
|
||||||
|
|
||||||
|
JScrollPane scrollPane = new JScrollPane(textArea);
|
||||||
|
TextPanel.add(scrollPane);
|
||||||
|
|
||||||
|
JPanel CenterPanel = new JPanel();
|
||||||
|
getContentPane().add(CenterPanel, BorderLayout.CENTER);
|
||||||
|
CenterPanel.setLayout(new BorderLayout(0, 0));
|
||||||
|
|
||||||
|
JPanel GameLayoutContainer = new JPanel();
|
||||||
|
CenterPanel.add(GameLayoutContainer);
|
||||||
|
GameLayoutContainer.setLayout(new BoxLayout(GameLayoutContainer, BoxLayout.X_AXIS));
|
||||||
|
|
||||||
|
JPanel GameAlignPanel = new JPanel();
|
||||||
|
GameLayoutContainer.add(GameAlignPanel);
|
||||||
|
GameAlignPanel.setLayout(null);
|
||||||
|
|
||||||
|
JPanel GameFieldPanel = new JPanel();
|
||||||
|
GameFieldPanel.setBounds(50, 67, 172, 172);
|
||||||
|
GameAlignPanel.add(GameFieldPanel);
|
||||||
|
|
||||||
|
JButton button1 = new JButton("1");
|
||||||
|
button1.setMinimumSize(new Dimension(50, 50));
|
||||||
|
GameFieldPanel.setLayout(new MigLayout("", "[50px][50px][]", "[50px][][]"));
|
||||||
|
|
||||||
|
JButton button2 = new JButton("2");
|
||||||
|
button2.setMinimumSize(new Dimension(50, 50));
|
||||||
|
GameFieldPanel.add(button2, "cell 1 0,grow");
|
||||||
|
GameFieldPanel.add(button1, "cell 0 0,alignx left,aligny top");
|
||||||
|
|
||||||
|
JButton button3 = new JButton("3");
|
||||||
|
button3.setMinimumSize(new Dimension(50, 50));
|
||||||
|
GameFieldPanel.add(button3, "cell 2 0");
|
||||||
|
|
||||||
|
JButton button4 = new JButton("4");
|
||||||
|
button4.setMinimumSize(new Dimension(50, 50));
|
||||||
|
GameFieldPanel.add(button4, "cell 0 1");
|
||||||
|
|
||||||
|
JButton button5 = new JButton("5");
|
||||||
|
button5.setMinimumSize(new Dimension(50, 50));
|
||||||
|
GameFieldPanel.add(button5, "cell 1 1");
|
||||||
|
|
||||||
|
JButton button6 = new JButton("6");
|
||||||
|
button6.setMinimumSize(new Dimension(50, 50));
|
||||||
|
GameFieldPanel.add(button6, "cell 2 1");
|
||||||
|
|
||||||
|
JButton button7 = new JButton("7");
|
||||||
|
button7.setMinimumSize(new Dimension(50, 50));
|
||||||
|
GameFieldPanel.add(button7, "cell 0 2");
|
||||||
|
|
||||||
|
JButton button8 = new JButton("8");
|
||||||
|
button8.setMinimumSize(new Dimension(50, 50));
|
||||||
|
GameFieldPanel.add(button8, "cell 1 2");
|
||||||
|
|
||||||
|
JButton button9 = new JButton("9");
|
||||||
|
button9.setMinimumSize(new Dimension(50, 50));
|
||||||
|
GameFieldPanel.add(button9, "cell 2 2");
|
||||||
|
|
||||||
|
this.buttons[0][0] = button1;
|
||||||
|
this.buttons[0][1] = button2;
|
||||||
|
this.buttons[0][2] = button3;
|
||||||
|
this.buttons[1][0] = button4;
|
||||||
|
this.buttons[1][1] = button5;
|
||||||
|
this.buttons[1][2] = button6;
|
||||||
|
this.buttons[2][0] = button7;
|
||||||
|
this.buttons[2][1] = button8;
|
||||||
|
this.buttons[2][2] = button9;
|
||||||
|
|
||||||
|
JPanel panel = new JPanel();
|
||||||
|
panel.setBounds(0, 269, 272, 35);
|
||||||
|
GameAlignPanel.add(panel);
|
||||||
|
panel.setLayout(new FormLayout(new ColumnSpec[] {
|
||||||
|
ColumnSpec.decode("127px"),
|
||||||
|
FormFactory.RELATED_GAP_COLSPEC,
|
||||||
|
FormFactory.DEFAULT_COLSPEC,
|
||||||
|
FormFactory.RELATED_GAP_COLSPEC,
|
||||||
|
FormFactory.DEFAULT_COLSPEC,},
|
||||||
|
new RowSpec[] {
|
||||||
|
RowSpec.decode("28px"),}));
|
||||||
|
|
||||||
|
JButton btnNeuesSpiel = new JButton("Neues Spiel");
|
||||||
|
btnNeuesSpiel.setPreferredSize(new Dimension(127, 28));
|
||||||
|
panel.add(btnNeuesSpiel, "1, 1, left, top");
|
||||||
|
btnNeuesSpiel.setFont(new Font("Tahoma", Font.PLAIN, 10));
|
||||||
|
btnNeuesSpiel.addMouseListener(this);
|
||||||
|
this.newGameButton = btnNeuesSpiel;
|
||||||
|
|
||||||
|
JButton btnSpielWiederholen = new JButton("Spiel wiederholen");
|
||||||
|
btnSpielWiederholen.setPreferredSize(new Dimension(127, 28));
|
||||||
|
panel.add(btnSpielWiederholen, "5, 1, left, top");
|
||||||
|
btnSpielWiederholen.addMouseListener(this);
|
||||||
|
btnSpielWiederholen.setFont(new Font("Tahoma", Font.PLAIN, 10));
|
||||||
|
this.repeatGameButton = btnSpielWiederholen;
|
||||||
|
setName("TicTacToeFrame");
|
||||||
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
setBounds(100, 100, 550, 500);
|
||||||
|
|
||||||
|
this.textArea = textArea;
|
||||||
|
this.scrollPane = scrollPane;
|
||||||
|
|
||||||
|
for(int x = 0; x < 3; x++) {
|
||||||
|
for(int y = 0; y < 3; y++) {
|
||||||
|
this.buttons[x][y].setText("");
|
||||||
|
this.buttons[x][y].addMouseListener(this);
|
||||||
|
this.buttons[x][y].setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handles turns based on incoming events.
|
||||||
|
* @param coords
|
||||||
|
*/
|
||||||
|
protected void handleTurn(int[] coords) {
|
||||||
|
//listen for event, then execute this
|
||||||
|
if(this.game.isGameOver() == false) {
|
||||||
|
this.game.getActivePlayer().setNextTurn(coords);
|
||||||
|
this.game.getActivePlayer().takeTurn(this.game);
|
||||||
|
this.game.drawField();
|
||||||
|
this.game.processGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses the given fieldSet to "draw" the current state of the field.
|
||||||
|
* @param FieldSet fieldSet
|
||||||
|
*/
|
||||||
|
public void drawField(FieldSet fieldSet) {
|
||||||
|
String text = "";
|
||||||
|
int[][] field = fieldSet.getFieldSet();
|
||||||
|
for(int x = 0; x < 3; x++) {
|
||||||
|
for(int y = 0; y < 3; y++) {
|
||||||
|
text = Integer.toString(field[x][y]);
|
||||||
|
if(text.equals("0")) text = "";
|
||||||
|
this.buttons[x][y].setText(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int[]
|
||||||
|
*/
|
||||||
|
public int[] askPlayerForField() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return String name
|
||||||
|
*/
|
||||||
|
public String askPlayerForName() {
|
||||||
|
return "JPT";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* append the text to the textarea and scroll down ;)
|
||||||
|
*/
|
||||||
|
public void message(String msg) {
|
||||||
|
try {
|
||||||
|
this.textArea.getDocument().insertString(this.textArea.getDocument().getLength(), msg + "\r\n", null);
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
//move the cursor down.
|
||||||
|
this.textArea.setCaretPosition(this.textArea.getText().length());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle the mouseClick and the turn accordingly :)
|
||||||
|
*/
|
||||||
|
public void mouseClicked(MouseEvent arg0) {
|
||||||
|
Component button = arg0.getComponent();
|
||||||
|
//if it was one of the 9 buttons, handle it...
|
||||||
|
for(int x = 0; x < 3; x++) {
|
||||||
|
for(int y = 0; y < 3; y++) {
|
||||||
|
if(this.buttons[x][y].equals(button)) {
|
||||||
|
this.handleTurn(new int[]{x,y});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(button.equals(this.newGameButton)) {
|
||||||
|
this.onNewGame();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(button.equals(this.repeatGameButton)) {
|
||||||
|
this.game.resetGame();
|
||||||
|
this.game.getView().drawField(this.game.getFieldSet());
|
||||||
|
this.game.processGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param newGameDialog
|
||||||
|
*/
|
||||||
|
public void setNewGameDialog(NewGameDialog dialog) {
|
||||||
|
this.newGameDialog = dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* swap the windows - it should be that easy ;)
|
||||||
|
*/
|
||||||
|
private void onNewGame() {
|
||||||
|
this.setVisible(false);
|
||||||
|
this.newGameDialog.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package org.jpt.tictactoe.gui;
|
||||||
|
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code entry point.
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
//show new game window...
|
||||||
|
NewGameDialog dialog = new NewGameDialog();
|
||||||
|
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
||||||
|
dialog.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,216 @@
|
||||||
|
package org.jpt.tictactoe.gui;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.FlowLayout;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseListener;
|
||||||
|
|
||||||
|
import javax.swing.DefaultComboBoxModel;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JComboBox;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
|
|
||||||
|
import org.jpt.tictactoe.AbstractPlayer;
|
||||||
|
import org.jpt.tictactoe.Game;
|
||||||
|
import org.jpt.tictactoe.Game.PlayerType;
|
||||||
|
|
||||||
|
import com.jgoodies.forms.factories.FormFactory;
|
||||||
|
import com.jgoodies.forms.layout.ColumnSpec;
|
||||||
|
import com.jgoodies.forms.layout.FormLayout;
|
||||||
|
import com.jgoodies.forms.layout.RowSpec;
|
||||||
|
|
||||||
|
public class NewGameDialog extends JDialog implements MouseListener {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final JPanel contentPanel = new JPanel();
|
||||||
|
private JTextField player1Name;
|
||||||
|
private JTextField player2Name;
|
||||||
|
|
||||||
|
protected JTextField player1NameField;
|
||||||
|
protected JTextField player2NameField;
|
||||||
|
|
||||||
|
protected JComboBox player1TypeField;
|
||||||
|
protected JComboBox player2TypeField;
|
||||||
|
|
||||||
|
protected JButton okButton;
|
||||||
|
protected JButton cancelButton;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the dialog.
|
||||||
|
*/
|
||||||
|
public NewGameDialog() {
|
||||||
|
setTitle("Neues Spiel");
|
||||||
|
setBounds(100, 100, 450, 185);
|
||||||
|
getContentPane().setLayout(new BorderLayout());
|
||||||
|
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||||
|
getContentPane().add(contentPanel, BorderLayout.CENTER);
|
||||||
|
contentPanel.setLayout(new BorderLayout(0, 0));
|
||||||
|
{
|
||||||
|
JPanel panel = new JPanel();
|
||||||
|
contentPanel.add(panel, BorderLayout.NORTH);
|
||||||
|
{
|
||||||
|
JLabel lblEinNeuesTictactoe = new JLabel("Ein neues TicTacToe beginnen!");
|
||||||
|
lblEinNeuesTictactoe.setFont(new Font("Tahoma", Font.PLAIN, 14));
|
||||||
|
panel.add(lblEinNeuesTictactoe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
JPanel panel = new JPanel();
|
||||||
|
contentPanel.add(panel, BorderLayout.CENTER);
|
||||||
|
FormLayout fl_panel = new FormLayout(new ColumnSpec[] {
|
||||||
|
FormFactory.RELATED_GAP_COLSPEC,
|
||||||
|
FormFactory.DEFAULT_COLSPEC,
|
||||||
|
FormFactory.RELATED_GAP_COLSPEC,
|
||||||
|
ColumnSpec.decode("default:grow"),
|
||||||
|
FormFactory.RELATED_GAP_COLSPEC,
|
||||||
|
FormFactory.DEFAULT_COLSPEC,
|
||||||
|
FormFactory.RELATED_GAP_COLSPEC,
|
||||||
|
ColumnSpec.decode("default:grow"),
|
||||||
|
FormFactory.RELATED_GAP_COLSPEC,
|
||||||
|
ColumnSpec.decode("default:grow"),},
|
||||||
|
new RowSpec[] {
|
||||||
|
FormFactory.RELATED_GAP_ROWSPEC,
|
||||||
|
FormFactory.DEFAULT_ROWSPEC,
|
||||||
|
FormFactory.RELATED_GAP_ROWSPEC,
|
||||||
|
FormFactory.DEFAULT_ROWSPEC,
|
||||||
|
FormFactory.RELATED_GAP_ROWSPEC,
|
||||||
|
FormFactory.DEFAULT_ROWSPEC,
|
||||||
|
FormFactory.RELATED_GAP_ROWSPEC,
|
||||||
|
FormFactory.DEFAULT_ROWSPEC,});
|
||||||
|
panel.setLayout(fl_panel);
|
||||||
|
{
|
||||||
|
JLabel lblDeinName = new JLabel("Spieler 1");
|
||||||
|
panel.add(lblDeinName, "4, 2, right, default");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
JLabel lblSpieler = new JLabel("Spieler 2");
|
||||||
|
panel.add(lblSpieler, "8, 2");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
JLabel lblName = new JLabel("Name");
|
||||||
|
panel.add(lblName, "2, 4");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
player1Name = new JTextField();
|
||||||
|
panel.add(player1Name, "4, 4, fill, fill");
|
||||||
|
player1Name.setColumns(10);
|
||||||
|
this.player1NameField = player1Name;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
player2Name = new JTextField();
|
||||||
|
panel.add(player2Name, "8, 4, fill, default");
|
||||||
|
player2Name.setColumns(10);
|
||||||
|
this.player2NameField = player2Name;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
JLabel lblTyp = new JLabel("Spielertyp");
|
||||||
|
panel.add(lblTyp, "2, 6, right, default");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
JComboBox player1Type = new JComboBox();
|
||||||
|
player1Type.setModel(new DefaultComboBoxModel(PlayerType.values()));
|
||||||
|
panel.add(player1Type, "4, 6, fill, default");
|
||||||
|
this.player1TypeField = player1Type;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
JComboBox player2Type = new JComboBox();
|
||||||
|
player2Type.setModel(new DefaultComboBoxModel(PlayerType.values()));
|
||||||
|
panel.add(player2Type, "8, 6, fill, default");
|
||||||
|
this.player2TypeField = player2Type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
JPanel buttonPane = new JPanel();
|
||||||
|
buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
|
||||||
|
getContentPane().add(buttonPane, BorderLayout.SOUTH);
|
||||||
|
{
|
||||||
|
JButton okButton = new JButton("Los geht's!");
|
||||||
|
this.okButton = okButton;
|
||||||
|
okButton.addMouseListener(this);
|
||||||
|
okButton.setActionCommand("OK");
|
||||||
|
buttonPane.add(okButton);
|
||||||
|
getRootPane().setDefaultButton(okButton);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
JButton cancelButton = new JButton("Ach, doch keine Lust.");
|
||||||
|
this.cancelButton = cancelButton;
|
||||||
|
cancelButton.addMouseListener(this);
|
||||||
|
cancelButton.setActionCommand("Cancel");
|
||||||
|
buttonPane.add(cancelButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createNewGame() {
|
||||||
|
Game game = new Game();
|
||||||
|
|
||||||
|
String player1Name = this.player1NameField.getText();
|
||||||
|
String player2Name = this.player2NameField.getText();
|
||||||
|
|
||||||
|
PlayerType player1Type = (PlayerType) this.player1TypeField.getSelectedItem();
|
||||||
|
PlayerType player2Type = (PlayerType) this.player2TypeField.getSelectedItem();
|
||||||
|
|
||||||
|
AbstractPlayer player1 = game.createPlayerByEnum(player1Type, player1Name);
|
||||||
|
game.addPlayer(player1);
|
||||||
|
AbstractPlayer player2 = game.createPlayerByEnum(player2Type, player2Name);
|
||||||
|
game.addPlayer(player2);
|
||||||
|
|
||||||
|
//hide the other dialog.
|
||||||
|
this.setVisible(false);
|
||||||
|
|
||||||
|
GuiView guiView = new GuiView();
|
||||||
|
guiView.player1NameLabel.setText(player1Name);
|
||||||
|
guiView.player2NameLabel.setText(player2Name);
|
||||||
|
guiView.setNewGameDialog(this);
|
||||||
|
guiView.setVisible(true);
|
||||||
|
guiView.setGame(game);
|
||||||
|
game.setView(guiView);
|
||||||
|
game.processGame();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* closes the window - exits the application.
|
||||||
|
*/
|
||||||
|
private void closeWindow() {
|
||||||
|
this.dispose();
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mouseClicked(MouseEvent arg0) {
|
||||||
|
Component button = arg0.getComponent();
|
||||||
|
if(button.equals(this.okButton)) this.createNewGame();
|
||||||
|
if(button.equals(this.cancelButton)) this.closeWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package org.jpt.tictactoe.text;
|
||||||
|
|
||||||
|
import org.jpt.tictactoe.*;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code entry point.
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Game game = new Game();
|
||||||
|
AbstractView textView = new TextView();
|
||||||
|
textView.setGame(game);
|
||||||
|
game.setView(textView);
|
||||||
|
|
||||||
|
game.addPlayer(new HumanPlayer(game.getView().askPlayerForName()));
|
||||||
|
game.addPlayer(new DumbKi("Steve"));
|
||||||
|
|
||||||
|
//listen for event
|
||||||
|
while(game.isGameOver() == false) {
|
||||||
|
game.getActivePlayer().setNextTurn(game.getView().askPlayerForField());
|
||||||
|
game.getActivePlayer().takeTurn(game);
|
||||||
|
game.drawField();
|
||||||
|
game.processGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
package org.jpt.tictactoe.text;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
import org.jpt.tictactoe.*;
|
||||||
|
|
||||||
|
public class TextView implements AbstractView{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains the game. I need this to be consistent here.
|
||||||
|
* It's important for the Gui stuff.
|
||||||
|
* @var Game
|
||||||
|
*/
|
||||||
|
protected Game game;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param game
|
||||||
|
*/
|
||||||
|
public void setGame(Game game) {
|
||||||
|
this.game = game;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* uses system.out to print the field.
|
||||||
|
*/
|
||||||
|
public void drawField(FieldSet fieldSet) {
|
||||||
|
int[][] fields = fieldSet.getFieldSet();
|
||||||
|
String output = "";
|
||||||
|
String eol = "\r\n";
|
||||||
|
String horizontalLine = "-------------" + eol;
|
||||||
|
|
||||||
|
for(int i = 0; i<3; i++) {
|
||||||
|
output += horizontalLine;
|
||||||
|
for(int j = 0; j<3; j++) {
|
||||||
|
output += "| " + Integer.toString(fields[i][j]) + " ";
|
||||||
|
}
|
||||||
|
output += "|" + eol;
|
||||||
|
}
|
||||||
|
output += horizontalLine;
|
||||||
|
|
||||||
|
System.out.println(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int[] the coordinates.
|
||||||
|
*/
|
||||||
|
public int[] askPlayerForField() {
|
||||||
|
System.out.print("x,y >");
|
||||||
|
InputStreamReader converter = new InputStreamReader(System.in);
|
||||||
|
BufferedReader in = new BufferedReader(converter);
|
||||||
|
try {
|
||||||
|
String result = in.readLine();
|
||||||
|
String[] splitted = result.split(",");
|
||||||
|
int x = new Integer(splitted[0]);
|
||||||
|
int y = new Integer(splitted[1]);
|
||||||
|
int coords[] = new int[2];
|
||||||
|
coords[0] = x;
|
||||||
|
coords[1] = y;
|
||||||
|
this.message("You entered: " + result.toString());
|
||||||
|
return coords;
|
||||||
|
} catch (Exception e) {
|
||||||
|
this.message("Invalid turn - Please use the following format: [x,y] e.g. 2,1");
|
||||||
|
return this.askPlayerForField();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String askPlayerForName() {
|
||||||
|
System.out.print("Please enter your name: ");
|
||||||
|
InputStreamReader converter = new InputStreamReader(System.in);
|
||||||
|
BufferedReader in = new BufferedReader(converter);
|
||||||
|
try {
|
||||||
|
String result = in.readLine();
|
||||||
|
return result;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outputs the message.
|
||||||
|
* @param String msg
|
||||||
|
*/
|
||||||
|
public void message(String msg) {
|
||||||
|
System.out.println(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue