Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Stefano Cobelli
205_hw02
Commits
48fb94c0
Commit
48fb94c0
authored
Nov 14, 2014
by
Matt Tower
Browse files
Merge branch 'MattsBranch' of git@gitlab.bucknell.edu:sjc032/205_hw02.git into MattsBranch
parents
53cc1974
7e1abaaa
Changes
7
Hide whitespace changes
Inline
Side-by-side
src/controller/TTTController.java
View file @
48fb94c0
...
...
@@ -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
);
}
}
src/model/Board.java
View file @
48fb94c0
...
...
@@ -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
;
}
}
src/model/Game.java
View file @
48fb94c0
...
...
@@ -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
];
}
}
src/model/player/AIPlayer.java
View file @
48fb94c0
...
...
@@ -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
src/model/player/BlockerPlayer.java
View file @
48fb94c0
...
...
@@ -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
;
...
...
src/view/TTTControlPanel.java
View file @
48fb94c0
...
...
@@ -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
);
...
...
src/view/TTTPlayerPanel.java
View file @
48fb94c0
...
...
@@ -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
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment