Commit 8afa716a authored by Stefano Cobelli's avatar Stefano Cobelli

Redid random player

Controller was not ready for testing
AutoPlayable now returns an array of coors
parent 4fca81a3
......@@ -48,6 +48,7 @@ public class TTTController implements ActionListener {
private TTTPlayerPanel playerPanel;
/** an instance of an ai player. Not necessary as the hashtable is static */
private AIPlayer aiGuy;
/** */
/**
......@@ -70,6 +71,7 @@ public class TTTController implements ActionListener {
boardPanel.getButtonBoard()[i][j].addActionListener(this);
}
}
this.aiGuy = new AIPlayer(theGame.getBoard(), Mark.O);
}
......@@ -81,16 +83,18 @@ public class TTTController implements ActionListener {
*/
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == controlPanel.getNewGameButton()) {
newGame();
}
else if (e.getSource() == controlPanel.getTrainAIButton()) {
return;
} else if (e.getSource() == controlPanel.getTrainAIButton()) {
int trainCount = 0;
try {
trainCount = Integer.parseInt(controlPanel.getTrainNumberField().getText());
}catch(Exception ex) {
JOptionPane.showMessageDialog(null, "Please enter a valid number to train");
trainCount = Integer.parseInt(controlPanel
.getTrainNumberField().getText());
} catch (Exception ex) {
JOptionPane.showMessageDialog(null,
"Please enter a valid number to train");
return;
}
Game aiGames = new Game(theGame.getSize());
......@@ -100,7 +104,7 @@ public class TTTController implements ActionListener {
aiGames.setPlayerX(aiGuy);
aiGames.setPlayerO(randGuy);
for (int i = 0; i < trainCount; i++) {
while(aiGames.isPlayable()) {
while (aiGames.isPlayable()) {
((AutoPlayable) aiGames.getCurPlayer()).decideMove();
aiGames.switchTurn();
}
......@@ -113,8 +117,8 @@ public class TTTController implements ActionListener {
if (e.getSource() == boardPanel.getButtonBoard()[row][col]) {
if (theGame.getCurPlayer().move(row, col)) {
// sets text on button if marked
boardPanel.getButtonBoard()[row][col].setText(theGame
.getPlayerTurn());
boardPanel.getButtonBoard()[row][col]
.setText(theGame.getPlayerTurn());
if (!theGame.isPlayable()) {
// performs relative actions if game is over
if (theGame.getState() == State.WIN) {
......@@ -129,52 +133,90 @@ public class TTTController implements ActionListener {
incrementString(statsPanel
.getOWins().getText()));
newGame();
return;
} else if (theGame.getState() == State.DRAW) {
JOptionPane.showMessageDialog(null,
"The game's a draw!");
statsPanel.getDraws().setText(
incrementString(statsPanel.getDraws()
.getText()));
incrementString(statsPanel
.getDraws().getText()));
newGame();
return;
}
} else {
// if the game is playable, switch the turn
theGame.switchTurn();
statsPanel.getPlayerTurn().setText(
theGame.getPlayerTurn());
}
}
}
}
}
if (theGame.getCurPlayer() instanceof AutoPlayable) {
System.out.println("AI turn");
Integer[] aiMove = ((AutoPlayable) theGame.getCurPlayer())
.decideMove();
boardPanel.getButtonBoard()[aiMove[0]][aiMove[1]]
.setText(theGame.getPlayerTurn());
theGame.switchTurn();
statsPanel.getPlayerTurn().setText(theGame.getPlayerTurn());
if (!theGame.isPlayable()) {
// performs relative actions if game is over
if (theGame.getState() == State.WIN) {
JOptionPane.showMessageDialog(null,
theGame.getPlayerTurn() + " wins!");
if (theGame.getPlayerTurn() == "X")
statsPanel.getXWins().setText(
incrementString(statsPanel.getXWins()
.getText()));
else if (theGame.getPlayerTurn() == "O")
statsPanel.getOWins().setText(
incrementString(statsPanel.getOWins()
.getText()));
newGame();
return;
} else if (theGame.getState() == State.DRAW) {
JOptionPane.showMessageDialog(null,
"The game's a draw!");
statsPanel.getDraws()
.setText(
incrementString(statsPanel.getDraws()
.getText()));
newGame();
return;
}
}
}
}
}
/**
* sets up for a new game through the game object and gui. resets players according to the player pane.
* sets up for a new game through the game object and gui. resets players
* according to the player pane.
*/
public void newGame() {
theGame.newGame();
if (playerPanel.getGameModeComboBox().getSelectedItem() == "Player vs. Player") {
theGame.setPlayerX(new Player(theGame.getBoard(), Mark.X));
theGame.setPlayerO(new Player(theGame.getBoard(), Mark.O));
}else {
} else {
theGame.setPlayerX(new Player(theGame.getBoard(), Mark.X));
if (playerPanel.getaIComboBox().getSelectedItem() == "Random") {
theGame.setPlayerO(new RandomPlayer(theGame.getBoard(), Mark.O));
}
else if (playerPanel.getaIComboBox().getSelectedItem() == "Blocker") {
} else if (playerPanel.getaIComboBox().getSelectedItem() == "Blocker") {
theGame.setPlayerO(new BlockerPlayer(theGame.getBoard(), Mark.O));
}
else {
} else {
aiGuy.setMark(Mark.O);
theGame.setPlayerO(aiGuy);
}
}
clearGUI();
}
/**
* clears the GUI to all blanks ""
*/
......
......@@ -177,18 +177,20 @@ public class Game {
theBoard.clear();
currentPlayer = 0;
}
/**
* @param player to set as X
* @param player
* to set as X
*/
public void setPlayerX(Player player){
public void setPlayerX(Player player) {
players[0] = player;
}
/**
* @param player to set as O
* @param player
* to set as O
*/
public void setPlayerO(Player player){
players[0] = player;
public void setPlayerO(Player player) {
players[1] = player;
}
}
......@@ -7,12 +7,11 @@
*/
package model.player;
import java.util.ArrayList;
import java.util.Hashtable;
import model.Board;
import model.Mark;
import model.Board.State;
import model.Mark;
/**
* A player that learns from experience
......@@ -22,14 +21,18 @@ import model.Board.State;
*/
public class AIPlayer extends Player implements AutoPlayable {
/** a hashtable that stores moves done already. It stores the (potential) move by the ai,
* after the other player has gone, so the last mvoe done is always AIPlayer */
/**
* a hashtable that stores moves done already. It stores the (potential)
* move by the ai, after the other player has gone, so the last mvoe done is
* always AIPlayer
*/
private static Hashtable<Mark[][], Boolean> hashBoards = new Hashtable<Mark[][], Boolean>();
/** the last board hashed */
private static Mark[][] prevBoard;
/**
* constructor for the aiplayer, just calls the super
*
* @param theBoard
* @param myMark
*/
......@@ -43,62 +46,72 @@ public class AIPlayer extends Player implements AutoPlayable {
* @see model.player.AutoPlayable#decideMove()
*/
@Override
public boolean decideMove() {
public Integer[] decideMove() {
Mark[][] curBoard = twoDArrayDeepCopy(theBoard.getMarkArr());
for (int row = 0; row < theBoard.getSize(); row++) {
for (int col = 0; col < theBoard.getSize(); col++) {
if (curBoard[row][col] == Mark.NONE) {
curBoard[row][col] = getMark();
//if the board is a win
if (hashBoards.get(curBoard) == true) {
return move(row,col);
}
//if the board might lead to a win
else if (hashBoards.get(curBoard) == null){
// if the board is a win
if (hashBoards.get(curBoard) == null) {
prevBoard = twoDArrayDeepCopy(curBoard);
boolean moveSuccess = move(row, col);
//if the boards a win, set all the other spots to false, so it knows to win
move(row, col);
// if the boards a win, set all the other spots to
// false, so it knows to win
if (theBoard.getState() == State.WIN) {
hashBoards.put(curBoard,true);
hashBoards.put(curBoard, true);
curBoard[row][col] = Mark.NONE;
for (int row2 = 0; row < theBoard.getSize(); row++) {
for (int col2 = 0; col < theBoard.getSize(); col++) {
if(curBoard[row2][col2] == Mark.NONE && row2 != row && col2 != col){
if (curBoard[row2][col2] == Mark.NONE
&& row2 != row && col2 != col) {
curBoard[row2][col2] = getMark();
hashBoards.put(curBoard, false);
}
}
}
}
return moveSuccess;
Integer[] answer = { row, col };
return answer;
}
//if the move is ineligible or leads to a loss
// if the board might lead to a win
else if (hashBoards.get(curBoard) == true) {
move(row, col);
Integer[] answer = { row, col };
return answer;
}
// if the move is ineligible or leads to a loss
curBoard[row][col] = Mark.NONE;
}
}
}
//if all moves lead to a loss, forfeit
// if all moves lead to a loss, forfeit
hashBoards.put(prevBoard, false);
for (int row = 0; row < theBoard.getSize(); row++) {
for (int col = 0; col < theBoard.getSize(); col++) {
if (curBoard[row][col] == Mark.NONE)
return move(row,col);
if (curBoard[row][col] == Mark.NONE) {
Integer[] answer = { row, col };
return answer;
}
}
}
//board is finished
return false;
// board is finished
return null;
}
/**
* Makes a deep copy of a two dimensional Mark array
*
* @param board
* @return
*/
public static Mark[][] twoDArrayDeepCopy(Mark[][] board) {
Mark[][] newArray =(Mark[][]) board.clone();
//you have to clone all the
for(int row=0; row<board.length ;row++){
newArray[row]=(Mark[]) board[row].clone();
}
return newArray;
Mark[][] newArray = board.clone();
// you have to clone all the
for (int row = 0; row < board.length; row++) {
newArray[row] = board[row].clone();
}
return newArray;
}
}
\ No newline at end of file
......@@ -15,5 +15,5 @@ package model.player;
*/
public interface AutoPlayable {
public boolean decideMove();
public Integer[] decideMove();
}
......@@ -32,15 +32,18 @@ public class BlockerPlayer extends Player implements AutoPlayable {
* @see model.player.AutoPlayable#decideMove()
*/
@Override
public boolean decideMove() {
public Integer[] decideMove() {
Mark[] marks = new Mark[theBoard.getSize()];
// Rows
for (int row = 0; row < theBoard.getSize(); row++) {
for (int col = 0; col < theBoard.getSize(); col++) {
marks[row] = theBoard.getMark(row, col);
}
if (checkSpots(marks) != -1)
return move(row, checkSpots(marks));
if (checkSpots(marks) != -1) {
move(row, checkSpots(marks));
Integer[] answer = { row, checkSpots(marks) };
return answer;
}
marks = new Mark[theBoard.getSize()];
}
// Cols
......@@ -48,26 +51,36 @@ public class BlockerPlayer extends Player implements AutoPlayable {
for (int row = 0; row < theBoard.getSize(); row++) {
marks[col] = theBoard.getMark(row, col);
}
if (checkSpots(marks) != -1)
return move(checkSpots(marks), col);
if (checkSpots(marks) != -1) {
move(checkSpots(marks), col);
Integer[] answer = { checkSpots(marks), col };
return answer;
}
marks = new Mark[theBoard.getSize()];
}
// DiagNW
for (int rowCol = 0; rowCol < theBoard.getSize(); rowCol++) {
marks[rowCol] = (theBoard.getMark(rowCol, rowCol));
}
if (checkSpots(marks) != -1)
return move(checkSpots(marks), checkSpots(marks));
if (checkSpots(marks) != -1) {
move(checkSpots(marks), checkSpots(marks));
Integer[] answer = { checkSpots(marks), checkSpots(marks) };
return answer;
}
marks = new Mark[theBoard.getSize()];
// DiagNE
for (int rowCol = 0; rowCol < theBoard.getSize(); rowCol++) {
marks[rowCol] = theBoard.getMark(rowCol, theBoard.getSize()
marks[rowCol] = theBoard.getMark(rowCol, (theBoard.getSize() - 1)
- rowCol);
}
if (checkSpots(marks) != -1)
return move(checkSpots(marks), theBoard.getSize()
if (checkSpots(marks) != -1) {
move(checkSpots(marks), (theBoard.getSize() - 1)
- checkSpots(marks));
return false;
Integer[] answer = { checkSpots(marks),
(theBoard.getSize() - 1) - checkSpots(marks) };
return answer;
}
return null;
}
/**
......
......@@ -46,16 +46,24 @@ public class RandomPlayer extends Player implements AutoPlayable {
* @return - true if move was made successfully, false otherwise
*/
@Override
public boolean decideMove() {
for (int i = 0; i < theBoard.getSize(); i++) {
for (int j = 0; j < theBoard.getSize(); j++) {
if (theBoard.isEmpty(i, j)) {
rowOptions.add(i);
colOptions.add(j);
}
public Integer[] decideMove() {
int row = rand.nextInt(rowOptions.size());
int col = rand.nextInt(rowOptions.size());
for (int count = 0; count < theBoard.getSize(); count++) {
if (this.move(row, col)) {
Integer[] answer = { rowOptions.get(row), colOptions.get(col) };
return answer;
}
row++;
if (row > theBoard.getSize()) {
row = 0;
col++;
}
if (col > theBoard.getSize()) {
col = 0;
}
}
int randNum = rand.nextInt(rowOptions.size());
return move(rowOptions.get(randNum), colOptions.get(randNum));
return null;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment