From 8c69c62184ad097e41c0f5342ab61397321867aa Mon Sep 17 00:00:00 2001 From: Woody Folsom Date: Tue, 13 Nov 2012 10:38:34 -0500 Subject: [PATCH] Added simple GUI for 9x9 go. Use HUMAN_GUI player option. --- README.txt | 1 + .../woodyfolsom/msproj/StandAloneGame.java | 45 ++- .../woodyfolsom/msproj/gui/BoardState.java | 13 + src/net/woodyfolsom/msproj/gui/Collision.java | 6 + src/net/woodyfolsom/msproj/gui/Goban.java | 75 +++++ src/net/woodyfolsom/msproj/gui/GridPanel.java | 284 ++++++++++++++++++ src/net/woodyfolsom/msproj/gui/Stone.java | 6 + src/net/woodyfolsom/msproj/gui/wood3.jpg | Bin 0 -> 8175 bytes .../msproj/policy/HumanGuiInput.java | 54 ++++ .../woodyfolsom/msproj/policy/MonteCarlo.java | 2 +- .../msproj/policy/MonteCarloAMAF.java | 10 + 11 files changed, 485 insertions(+), 11 deletions(-) create mode 100644 README.txt create mode 100644 src/net/woodyfolsom/msproj/gui/BoardState.java create mode 100644 src/net/woodyfolsom/msproj/gui/Collision.java create mode 100644 src/net/woodyfolsom/msproj/gui/Goban.java create mode 100644 src/net/woodyfolsom/msproj/gui/GridPanel.java create mode 100644 src/net/woodyfolsom/msproj/gui/Stone.java create mode 100644 src/net/woodyfolsom/msproj/gui/wood3.jpg create mode 100644 src/net/woodyfolsom/msproj/policy/HumanGuiInput.java create mode 100644 src/net/woodyfolsom/msproj/policy/MonteCarloAMAF.java diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..d7263b1 --- /dev/null +++ b/README.txt @@ -0,0 +1 @@ +Wood texture is from open source Wordpress resource site wpliving.net. \ No newline at end of file diff --git a/src/net/woodyfolsom/msproj/StandAloneGame.java b/src/net/woodyfolsom/msproj/StandAloneGame.java index 3065407..ba20d68 100644 --- a/src/net/woodyfolsom/msproj/StandAloneGame.java +++ b/src/net/woodyfolsom/msproj/StandAloneGame.java @@ -3,6 +3,8 @@ package net.woodyfolsom.msproj; import java.util.ArrayList; import java.util.List; +import net.woodyfolsom.msproj.gui.Goban; +import net.woodyfolsom.msproj.policy.HumanGuiInput; import net.woodyfolsom.msproj.policy.HumanKeyboardInput; import net.woodyfolsom.msproj.policy.MonteCarloUCT; import net.woodyfolsom.msproj.policy.Policy; @@ -10,8 +12,12 @@ import net.woodyfolsom.msproj.policy.RandomMovePolicy; import net.woodyfolsom.msproj.policy.RootParallelization; public class StandAloneGame { + private static final double DEFAULT_KOMI = 5.5; + private static final int DEFAULT_NUM_GAMES = 1; + private static final int DEFAULT_SIZE = 9; + enum PLAYER_TYPE { - HUMAN, ROOT_PAR, UCT_FAST, UCT_SLOW + HUMAN, HUMAN_GUI, ROOT_PAR, UCT_FAST, UCT_SLOW }; public static void main(String[] args) { @@ -21,8 +27,23 @@ public class StandAloneGame { System.out .println("For example to play 10 games against MC UCT w/ slow moves: StandAloneGame UCT_SLOW HUMAN 10"); } + int nGames = DEFAULT_NUM_GAMES; + int size = DEFAULT_SIZE; + double komi = DEFAULT_KOMI; + + switch (args.length) { + case 5: + nGames = Integer.valueOf(args[4]); + case 4: + komi = Double.valueOf(args[3]); + case 3: + size = Integer.valueOf(args[2]); + break; + default: + System.out.println("Arguments #3-5 not specified. Using default size=" + size +", komi = " + komi +", nGames=" + nGames +"."); + } new StandAloneGame().playGame(parsePlayerType(args[0]), - parsePlayerType(args[1]), Integer.valueOf(args[2])); + parsePlayerType(args[1]), size, komi, nGames); } private static PLAYER_TYPE parsePlayerType(String playerTypeStr) { @@ -35,23 +56,25 @@ public class StandAloneGame { return PLAYER_TYPE.UCT_SLOW; } else if ("HUMAN".equalsIgnoreCase(playerTypeStr)) { return PLAYER_TYPE.HUMAN; + } else if ("HUMAN_GUI".equalsIgnoreCase(playerTypeStr)) { + return PLAYER_TYPE.HUMAN_GUI; } else { throw new RuntimeException("Unknown player type: " + playerTypeStr); } } public void playGame(PLAYER_TYPE playerType1, PLAYER_TYPE playerType2, - int rounds) { + int size, double komi, int rounds) { - Policy player1 = getPolicy(playerType1); - Policy player2 = getPolicy(playerType2); + GameConfig gameConfig = new GameConfig(size); + gameConfig.setKomi(komi); Referee referee = new Referee(); - referee.setPolicy(Player.BLACK, player1); - referee.setPolicy(Player.WHITE, player2); + referee.setPolicy(Player.BLACK, getPolicy(playerType1, gameConfig, Player.BLACK)); + referee.setPolicy(Player.WHITE, getPolicy(playerType2, gameConfig, Player.WHITE)); List results = new ArrayList(); - GameConfig gameConfig = new GameConfig(9); + for (int round = 0; round < rounds; round++) { results.add(referee.play(gameConfig)); } @@ -63,12 +86,14 @@ public class StandAloneGame { } } - private Policy getPolicy(PLAYER_TYPE playerType) { + private Policy getPolicy(PLAYER_TYPE playerType, GameConfig gameConfig, Player player) { switch (playerType) { case HUMAN: return new HumanKeyboardInput(); + case HUMAN_GUI: + return new HumanGuiInput(new Goban(gameConfig, player)); case ROOT_PAR: - return new RootParallelization(3, 6000L); + return new RootParallelization(4, 6000L); case UCT_SLOW: return new MonteCarloUCT(new RandomMovePolicy(), 4000L); case UCT_FAST: diff --git a/src/net/woodyfolsom/msproj/gui/BoardState.java b/src/net/woodyfolsom/msproj/gui/BoardState.java new file mode 100644 index 0000000..259503c --- /dev/null +++ b/src/net/woodyfolsom/msproj/gui/BoardState.java @@ -0,0 +1,13 @@ +package net.woodyfolsom.msproj.gui; + +public class BoardState { + + /** + * @param args + */ + public static void main(String[] args) { + // TODO Auto-generated method stub + + } + +} diff --git a/src/net/woodyfolsom/msproj/gui/Collision.java b/src/net/woodyfolsom/msproj/gui/Collision.java new file mode 100644 index 0000000..1e7cbfd --- /dev/null +++ b/src/net/woodyfolsom/msproj/gui/Collision.java @@ -0,0 +1,6 @@ +package net.woodyfolsom.msproj.gui; + +public class Collision { + + +} \ No newline at end of file diff --git a/src/net/woodyfolsom/msproj/gui/Goban.java b/src/net/woodyfolsom/msproj/gui/Goban.java new file mode 100644 index 0000000..136a041 --- /dev/null +++ b/src/net/woodyfolsom/msproj/gui/Goban.java @@ -0,0 +1,75 @@ +package net.woodyfolsom.msproj.gui; + +import java.awt.BorderLayout; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +import javax.swing.JFrame; + +import net.woodyfolsom.msproj.Action; +import net.woodyfolsom.msproj.GameConfig; +import net.woodyfolsom.msproj.GameState; +import net.woodyfolsom.msproj.Player; + +public class Goban extends JFrame implements KeyListener { + + private static final long serialVersionUID = 1L; + + //private GameState gameState; + private GridPanel gridPanel; + + /* + public static void main(String[] args) { + Goban goban = new Goban(); + goban.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + goban.setVisible(true); + goban.pack(); + }*/ + + public Goban(GameConfig gameConfig, Player guiPlayer) { + setLayout(new BorderLayout()); + this.gridPanel = new GridPanel(gameConfig, guiPlayer); + add(gridPanel,BorderLayout.CENTER); + addKeyListener(this); + + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setVisible(true); + pack(); + } + + public Action getAction() { + return gridPanel.getAction(); + } + + public void setGameState(GameState gameState) { + gridPanel.setGameState(gameState); + } + + @Override + public void keyPressed(KeyEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void keyReleased(KeyEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void keyTyped(KeyEvent arg0) { + switch (arg0.getKeyChar()) + { + /* + case 't' : + case 'T' : + //Player currentPlayer = GoGame.getNextPlayer(gameState.getPlayerToMove()); + //System.out.println("Switching players. Current player is now " + currentPlayer); + //gameState. + break;*/ + default : + System.out.println("Ignoring unbound key: " + arg0.getKeyChar()); + } + } +} diff --git a/src/net/woodyfolsom/msproj/gui/GridPanel.java b/src/net/woodyfolsom/msproj/gui/GridPanel.java new file mode 100644 index 0000000..a9b0bd3 --- /dev/null +++ b/src/net/woodyfolsom/msproj/gui/GridPanel.java @@ -0,0 +1,284 @@ +package net.woodyfolsom.msproj.gui; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.net.URL; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import javax.swing.ImageIcon; +import javax.swing.JPanel; + +import net.woodyfolsom.msproj.Action; +import net.woodyfolsom.msproj.GameBoard; +import net.woodyfolsom.msproj.GameConfig; +import net.woodyfolsom.msproj.GameState; +import net.woodyfolsom.msproj.Player; + +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 static final int BORDER_WIDTH = 10; + + private static final int DOT_WIDTH = 5; + private static final int STONE_WIDTH = DOT_WIDTH * 2; + + private Image backgroundImg; + private int boardSize; + + 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 actionQueue = new LinkedBlockingQueue(); + + private Player guiPlayer; + + private String[] COLS = { "A", "B", "C", "D", "E", "F", "G", "H", "J" }; + private String[] ROWS; + + public GridPanel(GameConfig gameConfig, Player guiPlayer) { + this.guiPlayer = guiPlayer; + + this.boardSize = gameConfig.getSize(); + + initRows(this.boardSize); + + this.setPreferredSize(new Dimension(BOARD_WIDTH + BORDER_WIDTH * 2, + BOARD_HEIGHT + 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 Action getAction() { + int timeLimit = 10; + TimeUnit timeUnit = TimeUnit.SECONDS; + + try { + Action action = actionQueue.poll(timeLimit, timeUnit); + if (action == null) { + return Action.NONE; + } + return action; + } catch (InterruptedException ie) { + System.out.println("Interrupted while waiting " + timeLimit + " " + timeUnit + "s for player to move."); + return Action.NONE; + } + } + + private void initRows(int boardSize) { + ROWS = new String[boardSize]; + for (int i = 0; i < boardSize; i++) { + ROWS[i] = Integer.valueOf(boardSize - i).toString(); + } + } + + // 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; + + return (x - BORDER_WIDTH/*- centerOffset*/) / intersectionSize; + } + + // 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; + + return (y - BORDER_WIDTH/*- centerOffset*/) / intersectionSize; + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + + // tile wood texture + int iw = backgroundImg.getWidth(this); + int ih = backgroundImg.getHeight(this); + if (iw > 0 && ih > 0) { + for (int x = 0; x < getWidth(); x += iw) { + for (int y = 0; y < getHeight(); y += ih) { + g.drawImage(backgroundImg, x, y, iw, ih, this); + } + } + } + + int intersectionSize = BOARD_WIDTH / 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); + } + } + + for (int row = 0; row < boardSize; row++) { + g.drawLine(centerOffset, centerOffset + row * intersectionSize, + intersectionSize * boardSize - centerOffset, centerOffset + + row * intersectionSize); + } + + for (int col = 0; col < boardSize; col++) { + g.drawLine(centerOffset + col * intersectionSize, centerOffset, + centerOffset + col * intersectionSize, intersectionSize + * 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); + + 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); + } + + 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, + centerOffset + row * intersectionSize + 5); + } + + if (gameState != null) { + GameBoard gameBoard = gameState.getGameBoard(); + + for (int row = 0; row < boardSize; row++) { + for (int col = 0; col < boardSize; col++) { + + char symbol = gameBoard.getSymbolAt(col,boardSize - row - 1); + + switch (symbol) { + case 'X' : + g.setColor(Color.BLACK); + break; + case 'O' : + g.setColor(Color.WHITE); + break; + default : + continue; + } + + g.fillOval(intersectionSize * col + centerOffset - STONE_WIDTH, + intersectionSize * row + centerOffset - STONE_WIDTH, + STONE_WIDTH * 2, STONE_WIDTH * 2); + } + } + } + } + + public void setGameState(GameState gameState) { + this.gameState = gameState; + } + + @Override + public void mouseDragged(MouseEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseMoved(MouseEvent arg0) { + this.mouseX = arg0.getX(); + this.mouseY = arg0.getY(); + + this.repaint(); + } + + @Override + public void mouseClicked(MouseEvent arg0) { + if (gameState == null) { + System.out.println("Wait your turn!"); + return; + } + + if (!actionQueue.isEmpty()) { + System.out.println("You already moved. Be patient!"); + return; + } + // ystem.out.println("Mouse clicked: " + arg0); + int row = getRow(mouseX, mouseY); + int column = getColumn(mouseX, mouseY); + + Player currentPlayer = gameState.getPlayerToMove(); + if (currentPlayer == guiPlayer) { + // gameState.playStone(guiPlayer, Action.getInstance(COLS[row] + + // ROWS[column])); + Action action = Action.getInstance(COLS[column] + ROWS[row]); + System.out.println("Made move: " + action); + actionQueue.add(action); + } else { + System.out.println("Not your turn!"); + } + + this.repaint(); + } + + @Override + public void mouseEntered(MouseEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseExited(MouseEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void mousePressed(MouseEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseReleased(MouseEvent arg0) { + // TODO Auto-generated method stub + + } + +} \ No newline at end of file diff --git a/src/net/woodyfolsom/msproj/gui/Stone.java b/src/net/woodyfolsom/msproj/gui/Stone.java new file mode 100644 index 0000000..aea1aeb --- /dev/null +++ b/src/net/woodyfolsom/msproj/gui/Stone.java @@ -0,0 +1,6 @@ +package net.woodyfolsom.msproj.gui; + +public class Stone { + + +} \ No newline at end of file diff --git a/src/net/woodyfolsom/msproj/gui/wood3.jpg b/src/net/woodyfolsom/msproj/gui/wood3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..adeb10db2ebcf9f91bea54e8e6a30878e8149f66 GIT binary patch literal 8175 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 literal 0 HcmV?d00001 diff --git a/src/net/woodyfolsom/msproj/policy/HumanGuiInput.java b/src/net/woodyfolsom/msproj/policy/HumanGuiInput.java new file mode 100644 index 0000000..65ce15b --- /dev/null +++ b/src/net/woodyfolsom/msproj/policy/HumanGuiInput.java @@ -0,0 +1,54 @@ +package net.woodyfolsom.msproj.policy; + +import java.io.IOException; +import java.util.Collection; + +import net.woodyfolsom.msproj.Action; +import net.woodyfolsom.msproj.GameConfig; +import net.woodyfolsom.msproj.GameState; +import net.woodyfolsom.msproj.Player; +import net.woodyfolsom.msproj.gui.Goban; + +public class HumanGuiInput implements Policy { + private Goban goban; + + public HumanGuiInput(Goban goban) { + this.goban = goban; + } + + @Override + public Action getAction(GameConfig gameConfig, GameState gameState, + Player player) { + Action action = null; + String input = ""; + + do { + System.out.println(player + + " to move: (Use GUI)"); + + goban.setGameState(gameState); + action = goban.getAction(); + + if (action.isNone()) { + System.out.println("No move was made within 10 seconds. Hurry up!"); + System.out.println(gameState); + continue; + } + } while (action == null); + + return action; + } + + @Override + public Action getAction(GameConfig gameConfig, GameState gameState, + Collection prohibitedActions, Player player) { + throw new UnsupportedOperationException("Not implemented"); + } + + @Override + public int getNumStateEvaluations() { + // TODO Auto-generated method stub + return 1; + } + +} diff --git a/src/net/woodyfolsom/msproj/policy/MonteCarlo.java b/src/net/woodyfolsom/msproj/policy/MonteCarlo.java index 4f3de3a..6137e94 100644 --- a/src/net/woodyfolsom/msproj/policy/MonteCarlo.java +++ b/src/net/woodyfolsom/msproj/policy/MonteCarlo.java @@ -13,7 +13,7 @@ import net.woodyfolsom.msproj.tree.GameTreeNode; import net.woodyfolsom.msproj.tree.MonteCarloProperties; public abstract class MonteCarlo implements Policy { - protected static final int ROLLOUT_DEPTH_LIMIT = 100; + protected static final int ROLLOUT_DEPTH_LIMIT = 400; protected int numStateEvaluations = 0; protected Policy movePolicy; diff --git a/src/net/woodyfolsom/msproj/policy/MonteCarloAMAF.java b/src/net/woodyfolsom/msproj/policy/MonteCarloAMAF.java new file mode 100644 index 0000000..7c46576 --- /dev/null +++ b/src/net/woodyfolsom/msproj/policy/MonteCarloAMAF.java @@ -0,0 +1,10 @@ +package net.woodyfolsom.msproj.policy; + + +public class MonteCarloAMAF extends MonteCarloUCT { + + public MonteCarloAMAF(Policy movePolicy, long searchTimeLimit) { + super(movePolicy, searchTimeLimit); + } + +} \ No newline at end of file