Commit 48fb94c0 authored by Matt Tower's avatar Matt Tower

Merge branch 'MattsBranch' of git@gitlab.bucknell.edu:sjc032/205_hw02.git into MattsBranch

parents 53cc1974 7e1abaaa
......@@ -12,7 +12,6 @@ import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
import model.Board;
import model.Board.State;
import model.Game;
import model.Mark;
......@@ -72,7 +71,11 @@ public class TTTController implements ActionListener {
}
}
this.aiGuy = new AIPlayer(theGame.getBoard(), Mark.O);
this.controlPanel.getNewGameButton().addActionListener(this);
this.controlPanel.getTrainAIButton().addActionListener(this);
this.playerPanel.getGameModeComboBox().addActionListener(this);
this.playerPanel.getaIComboBox().addActionListener(this);
newGame();
}
/*
......@@ -92,23 +95,50 @@ public class TTTController implements ActionListener {
try {
trainCount = Integer.parseInt(controlPanel
.getTrainNumberField().getText());
if (trainCount <= 0) {
throw new Exception();
}
} catch (Exception ex) {
JOptionPane.showMessageDialog(null,
"Please enter a valid number to train");
return;
}
Game aiGames = new Game(theGame.getSize());
Board aiBoard = new Board(theGame.getSize());
aiGuy = new AIPlayer(aiBoard, Mark.O);
RandomPlayer randGuy = new RandomPlayer(aiBoard, Mark.X);
aiGames.setPlayerX(aiGuy);
aiGames.setPlayerO(randGuy);
RandomPlayer randGuy = new RandomPlayer(aiGames.getBoard(), Mark.X);
aiGuy = new AIPlayer(aiGames.getBoard(), Mark.O);
aiGames.setPlayerX(randGuy);
aiGames.setPlayerO(aiGuy);
for (int i = 0; i < trainCount; i++) {
while (aiGames.isPlayable()) {
((AutoPlayable) aiGames.getCurPlayer()).decideMove();
aiGames.switchTurn();
System.out.println(aiGames.getBoard());
}
aiGames.newGame();
}
aiGuy = new AIPlayer(theGame.getBoard(), Mark.O);
// handles the statuses of the buttons availability
} else if (e.getSource() == playerPanel.getGameModeComboBox()
|| e.getSource() == playerPanel.getaIComboBox()) {
newGame();
if (playerPanel.getGameModeComboBox().getSelectedItem()
.equals("Player vs. Computer")) {
playerPanel.getaIComboBox().setEnabled(true);
if (playerPanel.getaIComboBox().getSelectedItem()
.equals("AI Player")) {
controlPanel.getTrainAIButton().setEnabled(true);
controlPanel.getTrainNumberField().setEnabled(true);
} else {
controlPanel.getTrainAIButton().setEnabled(false);
controlPanel.getTrainNumberField().setEnabled(false);
}
} else {
playerPanel.getaIComboBox().setEnabled(false);
controlPanel.getTrainAIButton().setEnabled(false);
controlPanel.getTrainNumberField().setEnabled(false);
}
}
// checks all grid buttons if it's the source
else {
......@@ -122,6 +152,10 @@ public class TTTController implements ActionListener {
if (!theGame.isPlayable()) {
// performs relative actions if game is over
if (theGame.getState() == State.WIN) {
if (theGame.getOtherPlayer() instanceof AIPlayer) {
((AIPlayer) theGame.getOtherPlayer())
.loss();
}
JOptionPane.showMessageDialog(null,
theGame.getPlayerTurn() + " wins!");
if (theGame.getPlayerTurn() == "X")
......@@ -155,7 +189,6 @@ public class TTTController implements ActionListener {
}
}
if (theGame.getCurPlayer() instanceof AutoPlayable) {
System.out.println("AI turn");
Integer[] aiMove = ((AutoPlayable) theGame.getCurPlayer())
.decideMove();
boardPanel.getButtonBoard()[aiMove[0]][aiMove[1]]
......@@ -164,6 +197,7 @@ public class TTTController implements ActionListener {
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")
......@@ -239,4 +273,5 @@ public class TTTController implements ActionListener {
public String incrementString(String num) {
return String.valueOf(Integer.parseInt(num) + 1);
}
}
......@@ -282,11 +282,23 @@ public class Board {
public boolean isWinFor(Player player) {
return (updateBoardState() == player.getMark());
}
/**\
/**
* \
*
* @return board as a Mark[][]
*/
public Mark[][] getMarkArr() {
return board;
}
public boolean isSameBoard(Board otherBoard) {
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
if (this.getMarkArr()[row][col] != otherBoard.getMarkArr()[row][col])
return false;
}
}
return true;
}
}
......@@ -193,4 +193,13 @@ public class Game {
public void setPlayerO(Player player) {
players[1] = player;
}
/**
* @return the player who's turn it isn't
*/
public Player getOtherPlayer() {
if (currentPlayer == 0)
return players[1];
return players[0];
}
}
......@@ -7,7 +7,9 @@
*/
package model.player;
import java.util.Hashtable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import model.Board;
import model.Board.State;
......@@ -26,9 +28,13 @@ public class AIPlayer extends Player implements AutoPlayable {
* 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>();
private static HashMap<Integer, Boolean> hashBoards = new HashMap<Integer, Boolean>();
/** */
private static List<Board> winBoards = new ArrayList<Board>();
/** */
private static List<Board> loseBoards = new ArrayList<Board>();
/** the last board hashed */
private static Mark[][] prevBoard;
private static Board prevBoard;
/**
* constructor for the aiplayer, just calls the super
......@@ -47,56 +53,56 @@ public class AIPlayer extends Player implements AutoPlayable {
*/
@Override
public Integer[] decideMove() {
Mark[][] curBoard = twoDArrayDeepCopy(theBoard.getMarkArr());
Board answerBoard = new Board(theBoard.getSize());
Board curBoard = new Board(theBoard.getSize());
curBoard = boardDeepCopy(theBoard);
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) == null) {
prevBoard = twoDArrayDeepCopy(curBoard);
if (curBoard.isEmpty(row, col)) {
curBoard.setMark(row, col, getMark());
answerBoard = isBoardInList(curBoard, winBoards);
if (answerBoard != null) {
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);
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) {
curBoard[row2][col2] = getMark();
hashBoards.put(curBoard, false);
}
}
}
}
Integer[] answer = { row, col };
return answer;
}
// if the board might lead to a win
else if (hashBoards.get(curBoard) == true) {
move(row, col);
Integer[] answer = { row, col };
return answer;
curBoard = boardDeepCopy(theBoard);
}
}
}
curBoard = boardDeepCopy(theBoard);
for (int row = 0; row < theBoard.getSize(); row++) {
for (int col = 0; col < theBoard.getSize(); col++) {
if (curBoard.isEmpty(row, col)) {
curBoard.setMark(row, col, getMark());
answerBoard = isBoardInList(curBoard, loseBoards);
if (answerBoard != null) {
curBoard = boardDeepCopy(theBoard);
continue;
}
// if the move is ineligible or leads to a loss
curBoard[row][col] = Mark.NONE;
move(row, col);
if (theBoard.getState() == State.WIN) {
winBoards.add(curBoard);
}
prevBoard = boardDeepCopy(theBoard);
Integer[] answer = { row, col };
return answer;
}
}
}
// 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) {
if (curBoard.isEmpty(row, col)) {
if (isBoardInList(prevBoard, loseBoards) != null)
loseBoards.add(prevBoard);
move(row, col);
Integer[] answer = { row, col };
return answer;
}
}
}
// board is finished
return null;
}
......@@ -106,12 +112,32 @@ public class AIPlayer extends Player implements AutoPlayable {
* @param board
* @return
*/
public static Mark[][] twoDArrayDeepCopy(Mark[][] board) {
Mark[][] newArray = board.clone();
// you have to clone all the
for (int row = 0; row < board.length; row++) {
newArray[row] = board[row].clone();
public Board boardDeepCopy(Board oldBoard) {
Board newBoard = new Board(oldBoard.getSize());
for (int row = 0; row < oldBoard.getSize(); row++) {
for (int col = 0; col < oldBoard.getSize(); col++) {
newBoard.setMark(row, col, oldBoard.getMark(row, col));
}
}
return newBoard;
}
public void loss() {
if (isBoardInList(prevBoard, loseBoards) == null)
loseBoards.add(prevBoard);
}
public Board isBoardInList(Board board1, List<Board> list) {
for (int i = 0; i < list.size(); i++) {
if (board1.isSameBoard(list.get(i)))
return list.get(i);
}
return null;
}
public void printList(List<Board> l) {
for (Board i : l) {
System.out.println(i);
}
return newArray;
}
}
\ No newline at end of file
......@@ -7,6 +7,7 @@
*/
package model.player;
import java.util.Arrays;
import java.util.Random;
import model.Board;
......@@ -39,27 +40,29 @@ public class BlockerPlayer extends Player implements AutoPlayable {
// Rows
for (int row = 0; row < theBoard.getSize(); row++) {
for (int col = 0; col < theBoard.getSize(); col++) {
marks[row] = theBoard.getMark(row, col);
marks[col] = theBoard.getMark(row, col);
}
if (checkSpots(marks) != -1) {
move(row, checkSpots(marks));
Integer[] answer = { row, checkSpots(marks) };
return answer;
}
marks = new Mark[theBoard.getSize()];
Arrays.fill(marks, null);
}
// Cols
for (int col = 0; col < theBoard.getSize(); col++) {
for (int row = 0; row < theBoard.getSize(); row++) {
marks[col] = theBoard.getMark(row, col);
marks[row] = theBoard.getMark(row, col);
}
if (checkSpots(marks) != -1) {
move(checkSpots(marks), col);
Integer[] answer = { checkSpots(marks), col };
return answer;
}
marks = new Mark[theBoard.getSize()];
Arrays.fill(marks, null);
}
// DiagNW
for (int rowCol = 0; rowCol < theBoard.getSize(); rowCol++) {
marks[rowCol] = (theBoard.getMark(rowCol, rowCol));
......@@ -70,6 +73,7 @@ public class BlockerPlayer extends Player implements AutoPlayable {
return answer;
}
marks = new Mark[theBoard.getSize()];
Arrays.fill(marks, null);
// DiagNE
for (int rowCol = 0; rowCol < theBoard.getSize(); rowCol++) {
marks[rowCol] = theBoard.getMark(rowCol, (theBoard.getSize() - 1)
......@@ -83,6 +87,37 @@ public class BlockerPlayer extends Player implements AutoPlayable {
return answer;
}
// prioritizing middle
if (theBoard.isEmpty(theBoard.getSize() / 2, theBoard.getSize() / 2)) {
move(theBoard.getSize() / 2, theBoard.getSize() / 2);
Integer[] answer = { theBoard.getSize() / 2, theBoard.getSize() / 2 };
return answer;
}
// top left corner
if (theBoard.isEmpty(0, 0)) {
move(0, 0);
Integer[] answer = { 0, 0 };
return answer;
}
// top right corner
if (theBoard.isEmpty(theBoard.getSize() - 1, 0)) {
move(theBoard.getSize() - 1, 0);
Integer[] answer = { theBoard.getSize() - 1, 0 };
return answer;
}
// bottom left corner
if (theBoard.isEmpty(0, theBoard.getSize() - 1)) {
move(0, theBoard.getSize() - 1);
Integer[] answer = { 0, theBoard.getSize() - 1 };
return answer;
}
// bottom right corner
if (theBoard.isEmpty(theBoard.getSize() - 1, theBoard.getSize() - 1)) {
move(theBoard.getSize() - 1, theBoard.getSize() - 1);
Integer[] answer = { theBoard.getSize() - 1, theBoard.getSize() - 1 };
return answer;
}
Integer[][] coors = new Integer[theBoard.getSize() * theBoard.getSize()][2];
int index = 0;
for (int row = 0; row < theBoard.getSize(); row++) {
......@@ -115,7 +150,7 @@ public class BlockerPlayer extends Player implements AutoPlayable {
if (marks[i] == this.getMark())
return -1;
if (marks[i] == Mark.NONE) {
if (openSpot == -1)
if (openSpot != -1)
return -1;
else
openSpot = i;
......
......@@ -32,6 +32,8 @@ public class TTTControlPanel extends JPanel {
this.trainAIButton = new JButton("Train AI");
this.trainNumberField = new JTextField("10000");
String[] gameModeOptions = { "Player vs. Computer", "Player vs. Player" };
this.trainAIButton.setEnabled(false);
this.trainNumberField.setEnabled(false);
this.add(this.newGameButton);
this.add(this.trainAIButton);
this.add(this.trainNumberField);
......
......@@ -27,8 +27,9 @@ public class TTTPlayerPanel extends JPanel {
private static final long serialVersionUID = 1L;
private JComboBox gameModeComboBox;
private JComboBox aIComboBox;
private String[] gameModeOptions = { "Player vs. Computer", "Player vs. Player" };
private String[] aIOptions = { "Random", "Blocker", "AI Player" };
private String[] gameModeOptions = { "Player vs. Player",
"Player vs. Computer" };
private String[] aIOptions = { "Random", "Blocker", "AI Player" };
public TTTPlayerPanel() {
this.setLayout(new GridLayout(2, 2, 5, 5));
......@@ -38,6 +39,7 @@ public class TTTPlayerPanel extends JPanel {
JLabel aIText = new JLabel("Computer Player:", SwingConstants.CENTER);
this.gameModeComboBox = new JComboBox(gameModeOptions);
this.aIComboBox = new JComboBox(aIOptions);
this.aIComboBox.setEnabled(false);
this.add(gameModeText);
this.add(gameModeComboBox);
this.add(aIText);
......@@ -57,7 +59,7 @@ public class TTTPlayerPanel extends JPanel {
public JComboBox getaIComboBox() {
return aIComboBox;
}
public String[] getGameModeOptions() {
return gameModeOptions;
}
......
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