GUI updates. Added sound effect for playing a stone.

This commit is contained in:
2012-11-15 04:02:05 -05:00
parent 4d38c2bc20
commit e01060bc11
5 changed files with 148 additions and 61 deletions

View File

@@ -39,7 +39,13 @@ public class Referee {
GameRecord gameRecord = new GameRecord(gameConfig);
System.out.println("Game started.");
GameState initialGameState = gameRecord.getGameState(gameRecord.getNumTurns());
//Allow policy / GUI to do setup.
blackPolicy.setState(initialGameState);
whitePolicy.setState(initialGameState);
try {
while (!gameRecord.isFinished()) {
GameState gameState = gameRecord.getGameState(gameRecord.getNumTurns());

View File

@@ -3,6 +3,8 @@ package net.woodyfolsom.msproj.gui;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
@@ -12,16 +14,32 @@ import net.woodyfolsom.msproj.Action;
import net.woodyfolsom.msproj.GameConfig;
import net.woodyfolsom.msproj.GameState;
import net.woodyfolsom.msproj.Player;
import net.woodyfolsom.msproj.sfx.SfxPlayer;
public class Goban extends JFrame {
private static final long serialVersionUID = 1L;
private GridPanel gridPanel;
private SfxPlayer sfxPlayer;
public Goban(GameConfig gameConfig, Player guiPlayer) {
setLayout(new BorderLayout());
this.gridPanel = new GridPanel(gameConfig, guiPlayer);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
sfxPlayer.cleanup();
}
});
try {
sfxPlayer = new SfxPlayer();
} catch (Exception ex) {
System.out.println("Unable to initialize click sound due to: " + ex.getMessage());
}
this.gridPanel = new GridPanel(gameConfig, guiPlayer, sfxPlayer);
add(gridPanel,BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

View File

@@ -1,6 +1,7 @@
package net.woodyfolsom.msproj.gui;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
@@ -19,14 +20,15 @@ import net.woodyfolsom.msproj.GameBoard;
import net.woodyfolsom.msproj.GameConfig;
import net.woodyfolsom.msproj.GameState;
import net.woodyfolsom.msproj.Player;
import net.woodyfolsom.msproj.sfx.SfxPlayer;
public class GridPanel extends JPanel implements MouseListener,
MouseMotionListener {
private static final long serialVersionUID = 1L;
private static final int BOARD_HEIGHT = 300;
private static final int BOARD_WIDTH = 300;
private final int boardPixelWidth;
private static final int BORDER_WIDTH = 10;
private static final int DOT_WIDTH = 5;
@@ -37,43 +39,36 @@ public class GridPanel extends JPanel implements MouseListener,
private int mouseX = 0;
private int mouseY = 0;
//
private char[][] board;
//private static final char WHITE = 'O';
//private static final char BLACK = 'X';
private static final char EMPTY = '.';
//
private GameState gameState;
private LinkedBlockingQueue<Action> actionQueue = new LinkedBlockingQueue<Action>();
private Player guiPlayer;
private String[] COLS = { "A", "B", "C", "D", "E", "F", "G", "H", "J" };
private SfxPlayer sfxPlayer;
private String[] COLS = { "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T" };
private String[] ROWS;
public GridPanel(GameConfig gameConfig, Player guiPlayer) {
public GridPanel(GameConfig gameConfig, Player guiPlayer, SfxPlayer sfxPlayer) {
this.guiPlayer = guiPlayer;
this.sfxPlayer = sfxPlayer;
this.boardSize = gameConfig.getSize();
initRows(this.boardSize);
this.setPreferredSize(new Dimension(BOARD_WIDTH + BORDER_WIDTH * 2,
BOARD_HEIGHT + BORDER_WIDTH * 2));
if (boardSize <= 9) {
boardPixelWidth = 300;
} else if (boardSize <= 13) {
boardPixelWidth = 434;
} else {
boardPixelWidth = 634;
}
this.setPreferredSize(new Dimension(boardPixelWidth + BORDER_WIDTH * 2,
boardPixelWidth + BORDER_WIDTH * 2));
URL urlBackgroundImg = getClass().getResource("wood3.jpg");
this.backgroundImg = new ImageIcon(urlBackgroundImg).getImage();
this.addMouseListener(this);
this.addMouseMotionListener(this);
//
board = new char[boardSize][boardSize];
for (int i = 0; i < boardSize; i++) {
for (int j = 0; j < boardSize; j++) {
board[i][j] = EMPTY;
}
}
}
public void addAction(Action action) {
@@ -106,7 +101,7 @@ public class GridPanel extends JPanel implements MouseListener,
// Given a pair of (x,y) coordinates (pixels), returns a row index in the
// range [0..(boardSize-1)].
private int getColumn(int x, int y) {
int intersectionSize = BOARD_WIDTH / boardSize;
int intersectionSize = boardPixelWidth / boardSize;
return (x - BORDER_WIDTH/*- centerOffset*/) / intersectionSize;
}
@@ -114,7 +109,7 @@ public class GridPanel extends JPanel implements MouseListener,
// Given a pair of (x,y) coordinates (pixels), returns a row index in the
// range [0..(boardSize-1)].
private int getRow(int x, int y) {
int intersectionSize = BOARD_WIDTH / boardSize;
int intersectionSize = boardPixelWidth / boardSize;
return (y - BORDER_WIDTH/*- centerOffset*/) / intersectionSize;
}
@@ -134,19 +129,13 @@ public class GridPanel extends JPanel implements MouseListener,
}
}
int intersectionSize = BOARD_WIDTH / boardSize;
int intersectionSize = boardPixelWidth / boardSize;
int centerOffset = intersectionSize / 2;
g.translate(BORDER_WIDTH, BORDER_WIDTH);
for (int row = 0; row < boardSize; row++) {
for (int col = 0; col < boardSize; col++) {
g.fillOval(intersectionSize * col + centerOffset - DOT_WIDTH,
intersectionSize * row + centerOffset - DOT_WIDTH,
DOT_WIDTH * 2, DOT_WIDTH * 2);
}
}
g.setColor(Color.BLACK);
for (int row = 0; row < boardSize; row++) {
g.drawLine(centerOffset, centerOffset + row * intersectionSize,
intersectionSize * boardSize - centerOffset, centerOffset
@@ -159,31 +148,17 @@ public class GridPanel extends JPanel implements MouseListener,
* boardSize - centerOffset);
}
Color defaultColor = g.getColor();
g.setColor(Color.YELLOW);
int stoneX = getColumn(mouseX, mouseY) * intersectionSize
+ centerOffset;
int stoneY = getRow(mouseX, mouseY) * intersectionSize + centerOffset;
g.drawOval(stoneX - STONE_WIDTH, stoneY - STONE_WIDTH, STONE_WIDTH * 2,
STONE_WIDTH * 2);
g.setColor(defaultColor);
int mouseCol = getColumn(mouseX, mouseY);
int mouseRow = getRow(mouseX, mouseY);
for (int col = 0; col < boardSize; col++) {
// g.drawLine(centerOffset + col * intersectionSize, centerOffset,
// centerOffset + col * intersectionSize, intersectionSize *
// boardSize - centerOffset);
g.drawBytes(COLS[col].getBytes(), 0, 1, centerOffset + col
* intersectionSize - 5, BOARD_WIDTH + 5);
* intersectionSize - 5, boardPixelWidth + 5);
}
for (int row = 0; row < boardSize; row++) {
// g.drawLine(centerOffset + col * intersectionSize, centerOffset,
// centerOffset + col * intersectionSize, intersectionSize *
// boardSize - centerOffset);
g.drawBytes(ROWS[row].getBytes(), 0, 1, BOARD_WIDTH - 5,
byte[] bytes = ROWS[row].getBytes();
g.drawBytes(bytes, 0, bytes.length, boardPixelWidth - 5,
centerOffset + row * intersectionSize + 5);
}
@@ -196,19 +171,44 @@ public class GridPanel extends JPanel implements MouseListener,
char symbol = gameBoard.getSymbolAt(col,boardSize - row - 1);
switch (symbol) {
case 'X' :
case GameBoard.BLACK_STONE :
g.setColor(Color.BLACK);
g.fillOval(intersectionSize * col + centerOffset - STONE_WIDTH,
intersectionSize * row + centerOffset - STONE_WIDTH,
STONE_WIDTH * 2, STONE_WIDTH * 2);
break;
case 'O' :
case GameBoard.WHITE_STONE :
g.setColor(Color.WHITE);
g.fillOval(intersectionSize * col + centerOffset - STONE_WIDTH,
intersectionSize * row + centerOffset - STONE_WIDTH,
STONE_WIDTH * 2, STONE_WIDTH * 2);
break;
case GameBoard.EMPTY_INTERSECTION :
if (row == mouseRow && col == mouseCol && gameState.getPlayerToMove() == guiPlayer) {
if (guiPlayer == Player.BLACK) {
g.setColor(Color.BLACK);
} else if (guiPlayer == Player.WHITE) {
g.setColor(Color.WHITE);
} else {
throw new RuntimeException("Invalid guiPlayer: " + guiPlayer);
}
g.fillOval(intersectionSize * col + centerOffset - STONE_WIDTH,
intersectionSize * row + centerOffset - STONE_WIDTH,
STONE_WIDTH * 2, STONE_WIDTH * 2);
g.setColor(Color.RED);
g.drawOval(intersectionSize * col + centerOffset - STONE_WIDTH,
intersectionSize * row + centerOffset - STONE_WIDTH,
STONE_WIDTH * 2, STONE_WIDTH * 2);
} else {
g.setColor(Color.BLACK);
g.fillOval(intersectionSize * col + centerOffset - DOT_WIDTH,
intersectionSize * row + centerOffset - DOT_WIDTH,
DOT_WIDTH * 2, DOT_WIDTH * 2);
}
break;
default :
continue;
}
g.fillOval(intersectionSize * col + centerOffset - STONE_WIDTH,
intersectionSize * row + centerOffset - STONE_WIDTH,
STONE_WIDTH * 2, STONE_WIDTH * 2);
}
}
}
@@ -216,7 +216,21 @@ public class GridPanel extends JPanel implements MouseListener,
public void setGameState(GameState gameState) {
this.gameState = gameState;
if (gameState.getPlayerToMove() == guiPlayer || gameState.isTerminal()) {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
} else {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
}
this.repaint();
new Thread(new Runnable() {
@Override
public void run() {
sfxPlayer.play();
}}).start();
}
@Override
@@ -248,6 +262,14 @@ public class GridPanel extends JPanel implements MouseListener,
int row = getRow(mouseX, mouseY);
int column = getColumn(mouseX, mouseY);
if (row < 0 || row >= boardSize) {
return;
}
if (column < 0 || column >= boardSize) {
return;
}
Player currentPlayer = gameState.getPlayerToMove();
if (currentPlayer == guiPlayer) {
// gameState.playStone(guiPlayer, Action.getInstance(COLS[row] +

View File

@@ -0,0 +1,41 @@
package net.woodyfolsom.msproj.sfx;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
public class SfxPlayer {
private static final String clickFilename = "Click-SoundBible.com-1387633738.wav";
private Clip clip;
public SfxPlayer() throws LineUnavailableException, IOException, UnsupportedAudioFileException {
init();
}
public void cleanup() {
if (clip != null) {
clip.close();
}
}
public void init() throws LineUnavailableException, IOException, UnsupportedAudioFileException {
if (clip != null) {
clip.close();
}
InputStream inputStream = SfxPlayer.class.getResourceAsStream(clickFilename);
clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(inputStream));
}
public void play() {
if (clip!= null && !clip.isActive()) {
clip.setFramePosition(0);
clip.start();
}
}
}