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
8afa716a
Commit
8afa716a
authored
Nov 14, 2014
by
Stefano Cobelli
Browse files
Redid random player
Controller was not ready for testing AutoPlayable now returns an array of coors
parent
4fca81a3
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/controller/TTTController.java
View file @
8afa716a
...
...
@@ -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 ""
*/
...
...
src/model/Game.java
View file @
8afa716a
...
...
@@ -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
;
}
}
src/model/player/AIPlayer.java
View file @
8afa716a
...
...
@@ -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
src/model/player/AutoPlayable.java
View file @
8afa716a
...
...
@@ -15,5 +15,5 @@ package model.player;
*/
public
interface
AutoPlayable
{
public
boolean
decideMove
();
public
Integer
[]
decideMove
();
}
src/model/player/BlockerPlayer.java
View file @
8afa716a
...
...
@@ -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
;
}
/**
...
...
src/model/player/RandomPlayer.java
View file @
8afa716a
...
...
@@ -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
;
}
}
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