-The rest of the game engine. I screwed up the commit last time.

This commit is contained in:
Marshall
2012-03-31 14:18:08 -04:00
parent 2954041e89
commit 521fac6e08
45 changed files with 1006 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
package controller;
import model.Board.TileColor;
import model.CellPointer;
import model.Move;
public class PlayerController {
private final CellPointer cell = new CellPointer(0, 0);
private TileColor color = TileColor.BLUE;
private boolean ready = false;
public void denyMove() {
ready = false;
}
public TileColor getColor() {
return color;
}
public Move getMove() {
ready = false;
return new Move(cell, color);
}
public boolean isReady() {
return ready;
}
public void setCell(int row, int col) {
cell.r = row;
cell.c = col;
ready = true;
}
public void setColor(TileColor clr) {
color = clr;
}
}

BIN
src/img/blue.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
src/img/green.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
src/img/none.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
src/img/red.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
src/img/yellow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

163
src/model/Board.java Normal file
View File

@@ -0,0 +1,163 @@
package model;
import java.util.ArrayList;
public class Board {
public enum TileColor {
BLUE, GREEN, NONE, RED, YELLOW
}
public static final int NUM_COLS = 6;
public static final int NUM_ROWS = 6;
public static final int ROW_REMOVAL_SIZE = 3;
private final TileColor[][] board;
public Board() {
board = new TileColor[NUM_ROWS][NUM_COLS];
for (int r = 0; r < NUM_ROWS; r++) {
for (int c = 0; c < NUM_COLS; c++) {
setTile(new CellPointer(r, c), TileColor.NONE);
}
}
}
public TileColor getTile(int r, int c) {
return board[r][c];
}
public void setTile(CellPointer cp, TileColor tile) {
board[cp.r][cp.c] = tile;
if (tile != TileColor.NONE) {
ArrayList<CellPointer> remove = new ArrayList<CellPointer>();
ArrayList<CellPointer> hold;
int count;
// Check up-and-down.
count = 0;
hold = new ArrayList<CellPointer>();
loop: for (int row = cp.r; row >= 0; row--) {
if (board[row][cp.c] == tile) {
hold.add(new CellPointer(row, cp.c));
count++;
} else {
break loop;
}
}
loop: for (int row = cp.r + 1; row < NUM_ROWS; row++) {
if (board[row][cp.c] == tile) {
hold.add(new CellPointer(row, cp.c));
count++;
} else {
break loop;
}
}
if (count >= ROW_REMOVAL_SIZE) {
remove.addAll(hold);
}
// Check left-and-right.
count = 0;
hold = new ArrayList<CellPointer>();
loop: for (int col = cp.c; col >= 0; col--) {
if (board[cp.r][col] == tile) {
hold.add(new CellPointer(cp.r, col));
count++;
} else {
break loop;
}
}
loop: for (int col = cp.c + 1; col < NUM_COLS; col++) {
if (board[cp.r][col] == tile) {
hold.add(new CellPointer(cp.r, col));
count++;
} else {
break loop;
}
}
if (count >= ROW_REMOVAL_SIZE) {
remove.addAll(hold);
}
// Check descending diagonal.
count = 0;
hold = new ArrayList<CellPointer>();
int row = cp.r;
int col = cp.c;
loop: while (row >= 0 && col >= 0) {
if (board[row][col] == tile) {
hold.add(new CellPointer(row, col));
count++;
} else {
break loop;
}
row--;
col--;
}
row = cp.r + 1;
col = cp.c + 1;
loop: while (row < NUM_ROWS && col < NUM_COLS) {
if (board[row][col] == tile) {
hold.add(new CellPointer(row, col));
count++;
} else {
break loop;
}
row++;
col++;
}
if (count >= ROW_REMOVAL_SIZE) {
remove.addAll(hold);
}
// Check ascending diagonal.
count = 0;
hold = new ArrayList<CellPointer>();
row = cp.r;
col = cp.c;
loop: while (row < NUM_ROWS && col >= 0) {
if (board[row][col] == tile) {
hold.add(new CellPointer(row, col));
count++;
} else {
break loop;
}
row++;
col--;
}
row = cp.r - 1;
col = cp.c + 1;
loop: while (row >= 0 && col < NUM_COLS) {
if (board[row][col] == tile) {
hold.add(new CellPointer(row, col));
count++;
} else {
break loop;
}
row--;
col++;
}
if (count >= ROW_REMOVAL_SIZE) {
remove.addAll(hold);
}
for (CellPointer cell : remove) {
board[cell.r][cell.c] = TileColor.NONE;
}
}
}
}

View File

@@ -0,0 +1,11 @@
package model;
public class CellPointer {
public CellPointer(int row, int col) {
r = row;
c = col;
}
public int r;
public int c;
}

View File

@@ -0,0 +1,13 @@
package model;
public abstract class ComController {
protected Board board = null;
public ComController(Board brd) {
board = brd;
}
public abstract Move getMove();
}

21
src/model/Move.java Normal file
View File

@@ -0,0 +1,21 @@
package model;
import model.Board.TileColor;
public class Move {
private final TileColor color;
private final CellPointer cp;
public Move(CellPointer cllPntr, TileColor tlClr) {
cp = cllPntr;
color = tlClr;
}
public CellPointer getCell() {
return cp;
}
public TileColor getColor() {
return color;
}
}

154
src/model/Referee.java Normal file
View File

@@ -0,0 +1,154 @@
package model;
import javax.security.auth.Refreshable;
import model.Board.TileColor;
import model.comController.RandomComController;
import controller.PlayerController;
public class Referee implements Refreshable {
public enum Message {
COM_TURN {
@Override
public String toString() {
return "Waiting for the computer's move.";
}
},
GAME_OVER {
@Override
public String toString() {
return "Game over!";
}
},
NONE {
@Override
public String toString() {
return "";
}
},
PLAYER_TURN {
@Override
public String toString() {
return "Waiting for the player's move.";
}
}
}
private final Board board;
private final ComController cc;
private final PlayerController pc = new PlayerController();
private boolean playerTurn;
private boolean refresh = true;
private int score = 0;
public Referee() {
board = new Board();
cc = new RandomComController(board);
playerTurn = true;
}
public void doSomething() {
Move mv;
if (playerTurn && pc.isReady()) {
mv = pc.getMove();
if (board.getTile(mv.getCell().r, mv.getCell().c) == TileColor.NONE) {
playToken(pc.getMove());
refresh = true;
}
else {
pc.denyMove();
}
}
else if (!playerTurn) {
mv = cc.getMove();
playToken(mv);
refresh = true;
}
}
public ComController getCom() {
return cc;
}
public String getMessage() {
if (isOver()) {
return Message.GAME_OVER.toString();
}
else if (isPlayersTurn()) {
return Message.PLAYER_TURN.toString();
}
else {
return Message.COM_TURN.toString();
}
}
public PlayerController getPlayer() {
return pc;
}
public int getScore() {
return score;
}
public TileColor getTile(int r, int c) {
return board.getTile(r, c);
}
@Override
public boolean isCurrent() {
return !refresh;
}
public boolean isOver() {
for (int r = 0; r < Board.NUM_ROWS; r++) {
for (int c = 0; c < Board.NUM_COLS; c++) {
if (board.getTile(r, c) == TileColor.NONE) {
return false;
}
}
}
return true;
}
public void playToken(Move move) {
board.setTile(move.getCell(), move.getColor());
if (playerTurn) {
incrementScore();
}
incrementTurn();
}
@Override
public void refresh() {
refresh = false;
}
private void incrementScore() {
score++;
}
private void incrementTurn() {
playerTurn = !playerTurn;
}
private boolean isPlayersTurn() {
return playerTurn;
}
}

View File

@@ -0,0 +1,48 @@
package model.comController;
import java.util.Random;
import model.Board;
import model.Board.TileColor;
import model.CellPointer;
import model.ComController;
import model.Move;
public class RandomComController extends ComController {
private final Random rand = new Random();
public RandomComController(Board brd) {
super(brd);
}
@Override
public Move getMove() {
TileColor tile = TileColor.BLUE;
int r = -1;
int c = -1;
while (tile != TileColor.NONE) {
r = rand.nextInt(Board.NUM_ROWS);
c = rand.nextInt(Board.NUM_COLS);
tile = board.getTile(r, c);
}
switch (rand.nextInt(4)) {
case 0:
tile = TileColor.BLUE;
break;
case 1:
tile = TileColor.GREEN;
break;
case 2:
tile = TileColor.RED;
break;
case 3:
tile = TileColor.YELLOW;
}
return new Move(new CellPointer(r, c), tile);
}
}

120
src/view/BoardPanel.java Normal file
View File

@@ -0,0 +1,120 @@
package view;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.net.URL;
import javax.security.auth.Refreshable;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import model.Board;
import model.Referee;
public class BoardPanel extends JPanel implements Refreshable {
private class BoardPanelMouseListener implements MouseListener {
private final int col;
private final int row;
public BoardPanelMouseListener(int r, int c) {
row = r;
col = c;
}
@Override
public void mouseClicked(MouseEvent e) {
referee.getPlayer().setCell(row, col);
}
@Override
public void mouseEntered(MouseEvent arg0) {
// Nothing.
}
@Override
public void mouseExited(MouseEvent arg0) {
// Nothing.
}
@Override
public void mousePressed(MouseEvent arg0) {
// Nothing.
}
@Override
public void mouseReleased(MouseEvent arg0) {
// Nothing.
}
}
public static final URL BLUE_ICON = ClassLoader
.getSystemResource("img/blue.png");
public static final URL GREEN_ICON = ClassLoader
.getSystemResource("img/green.png");
public static final URL NONE_ICON = ClassLoader
.getSystemResource("img/none.png");
public static final URL RED_ICON = ClassLoader
.getSystemResource("img/red.png");
public static final URL YELLOW_ICON = ClassLoader
.getSystemResource("img/yellow.png");
/**
*
*/
private static final long serialVersionUID = 1L;
private final JLabel[][] board = new JLabel[Board.NUM_ROWS][Board.NUM_COLS];
private final Referee referee;
// private final ImageIcon[][] icons = new
// ImageIcon[Board.NUM_ROWS][Board.NUM_COLS];
public BoardPanel(Referee ref) {
referee = ref;
setLayout(new GridLayout(Board.NUM_ROWS, Board.NUM_COLS));
for (int r = 0; r < Board.NUM_ROWS; r++) {
for (int c = 0; c < Board.NUM_COLS; c++) {
board[r][c] = new JLabel(new ImageIcon(NONE_ICON));
board[r][c].addMouseListener(new BoardPanelMouseListener(r, c));
add(board[r][c]);
}
}
refresh();
}
@Override
public boolean isCurrent() {
return true;
}
@Override
public void refresh() {
for (int r = 0; r < Board.NUM_ROWS; r++) {
for (int c = 0; c < Board.NUM_COLS; c++) {
switch (referee.getTile(r, c)) {
case BLUE:
board[r][c].setIcon(new ImageIcon(BLUE_ICON));
break;
case GREEN:
board[r][c].setIcon(new ImageIcon(GREEN_ICON));
break;
case RED:
board[r][c].setIcon(new ImageIcon(RED_ICON));
break;
case YELLOW:
board[r][c].setIcon(new ImageIcon(YELLOW_ICON));
break;
default:
board[r][c].setIcon(new ImageIcon(NONE_ICON));
}
}
}
repaint();
}
}

134
src/view/MainFrame.java Normal file
View File

@@ -0,0 +1,134 @@
package view;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.ArrayList;
import javax.security.auth.RefreshFailedException;
import javax.security.auth.Refreshable;
import javax.swing.JFrame;
import model.Referee;
public class MainFrame extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
new MainFrame();
}
private final ArrayList<Refreshable> elements = new ArrayList<Refreshable>();
private final Referee game;
public MainFrame() {
game = new Referee();
init();
// Set up window.
setDefaultCloseOperation(MainFrame.EXIT_ON_CLOSE);
setResizable(false);
pack();
setLocationRelativeTo(null);
setVisible(true);
run();
}
private void init() {
// Create objects.
ScorePanel sp = new ScorePanel(game);
BoardPanel bp = new BoardPanel(game);
MessagePanel mp = new MessagePanel(game);
TileSelectionPanel tp = new TileSelectionPanel(game);
// Add refreshables.
elements.add(sp);
elements.add(bp);
elements.add(mp);
elements.add(tp);
// Add stuff to panel.
GridBagLayout layout = new GridBagLayout();
GridBagConstraints con;
con = new GridBagConstraints();
con.anchor = GridBagConstraints.WEST;
con.fill = GridBagConstraints.BOTH;
con.gridheight = 1;
con.gridwidth = 1;
con.gridx = 0;
con.gridy = 0;
con.weightx = 1;
layout.setConstraints(sp, con);
con = new GridBagConstraints();
con.anchor = GridBagConstraints.EAST;
con.fill = GridBagConstraints.BOTH;
con.gridheight = 1;
con.gridwidth = 1;
con.gridx = 1;
con.gridy = 0;
con.weightx = 1;
layout.setConstraints(mp, con);
con = new GridBagConstraints();
con.anchor = GridBagConstraints.NORTH;
con.fill = GridBagConstraints.BOTH;
con.gridwidth = 2;
con.gridx = 0;
con.gridy = 1;
layout.setConstraints(bp, con);
con = new GridBagConstraints();
con.anchor = GridBagConstraints.NORTH;
con.fill = GridBagConstraints.BOTH;
con.gridwidth = 2;
con.gridx = 0;
con.gridy = 2;
con.insets = new Insets(10, 0, 10, 0);
layout.setConstraints(tp, con);
setLayout(layout);
add(sp);
add(mp);
add(bp);
add(tp);
}
private void refresh() {
boolean change = false;
for (Refreshable r : elements) {
if (!game.isCurrent() || !r.isCurrent()) {
try {
r.refresh();
change = true;
} catch (RefreshFailedException e) {
e.printStackTrace();
}
}
}
if (change) {
game.refresh();
repaint();
pack();
}
}
private void run() {
while (!game.isOver()) {
game.doSomething();
refresh();
}
}
}

View File

@@ -0,0 +1,33 @@
package view;
import javax.security.auth.Refreshable;
import javax.swing.JLabel;
import javax.swing.JPanel;
import model.Referee;
public class MessagePanel extends JPanel implements Refreshable {
/**
*
*/
private static final long serialVersionUID = 1L;
private final JLabel message = new JLabel();
private final Referee referee;
public MessagePanel(Referee ref) {
referee = ref;
add(message);
}
@Override
public boolean isCurrent() {
return true;
}
@Override
public void refresh() {
message.setText(referee.getMessage());
}
}

33
src/view/ScorePanel.java Normal file
View File

@@ -0,0 +1,33 @@
package view;
import javax.security.auth.Refreshable;
import javax.swing.JLabel;
import javax.swing.JPanel;
import model.Referee;
public class ScorePanel extends JPanel implements Refreshable {
/**
*
*/
private static final long serialVersionUID = 1L;
private final JLabel message = new JLabel();
private final Referee referee;
public ScorePanel(Referee ref) {
referee = ref;
add(message);
}
@Override
public boolean isCurrent() {
return true;
}
@Override
public void refresh() {
message.setText("Score: " + referee.getScore());
}
}

View File

@@ -0,0 +1,236 @@
package view;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.security.auth.RefreshFailedException;
import javax.security.auth.Refreshable;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import model.Board.TileColor;
import model.Referee;
public class TileSelectionPanel extends JPanel implements Refreshable {
/**
*
*/
private static final long serialVersionUID = 1L;
private final JLabel blue = new JLabel(new ImageIcon(BoardPanel.BLUE_ICON));
private final JLabel green = new JLabel(
new ImageIcon(BoardPanel.GREEN_ICON));
private boolean isCurrent = true;
private final JLabel red = new JLabel(new ImageIcon(BoardPanel.RED_ICON));
private final Referee referee;
private final JLabel yellow = new JLabel(new ImageIcon(
BoardPanel.YELLOW_ICON));
public TileSelectionPanel(Referee ref) {
referee = ref;
initLayout();
initActions();
}
@Override
public boolean isCurrent() {
return isCurrent;
}
@Override
public void refresh() throws RefreshFailedException {
TileColor tile = referee.getPlayer().getColor();
blue.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
green.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
red.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
yellow.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
switch (tile) {
case GREEN:
green.setBorder(BorderFactory.createLineBorder(Color.RED, 3));
break;
case RED:
red.setBorder(BorderFactory.createLineBorder(Color.RED, 3));
break;
case YELLOW:
yellow.setBorder(BorderFactory.createLineBorder(Color.RED, 3));
break;
default:
blue.setBorder(BorderFactory.createLineBorder(Color.RED, 3));
break;
}
isCurrent = true;
}
private void initActions() {
blue.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent arg0) {
referee.getPlayer().setColor(TileColor.BLUE);
isCurrent = false;
}
@Override
public void mouseEntered(MouseEvent arg0) {
}
@Override
public void mouseExited(MouseEvent arg0) {
}
@Override
public void mousePressed(MouseEvent arg0) {
}
@Override
public void mouseReleased(MouseEvent arg0) {
}
});
green.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent arg0) {
referee.getPlayer().setColor(TileColor.GREEN);
isCurrent = false;
}
@Override
public void mouseEntered(MouseEvent arg0) {
}
@Override
public void mouseExited(MouseEvent arg0) {
}
@Override
public void mousePressed(MouseEvent arg0) {
}
@Override
public void mouseReleased(MouseEvent arg0) {
}
});
red.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent arg0) {
referee.getPlayer().setColor(TileColor.RED);
isCurrent = false;
}
@Override
public void mouseEntered(MouseEvent arg0) {
}
@Override
public void mouseExited(MouseEvent arg0) {
}
@Override
public void mousePressed(MouseEvent arg0) {
}
@Override
public void mouseReleased(MouseEvent arg0) {
}
});
yellow.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent arg0) {
referee.getPlayer().setColor(TileColor.YELLOW);
isCurrent = false;
}
@Override
public void mouseEntered(MouseEvent arg0) {
}
@Override
public void mouseExited(MouseEvent arg0) {
}
@Override
public void mousePressed(MouseEvent arg0) {
}
@Override
public void mouseReleased(MouseEvent arg0) {
}
});
}
private void initLayout() {
GridBagLayout layout = new GridBagLayout();
GridBagConstraints con;
JLabel spacer1 = new JLabel();
JLabel spacer2 = new JLabel();
con = new GridBagConstraints();
con.gridheight = 1;
con.gridwidth = 1;
con.gridx = 0;
con.gridy = 0;
con.weightx = 1;
layout.setConstraints(spacer1, con);
con = new GridBagConstraints();
con.gridheight = 1;
con.gridwidth = 1;
con.gridx = 1;
con.gridy = 0;
con.insets = new Insets(5, 5, 5, 5);
con.weightx = 0;
layout.setConstraints(blue, con);
con = new GridBagConstraints();
con.gridheight = 1;
con.gridwidth = 1;
con.gridx = 2;
con.gridy = 0;
con.insets = new Insets(5, 5, 5, 5);
con.weightx = 0;
layout.setConstraints(green, con);
con = new GridBagConstraints();
con.gridheight = 1;
con.gridwidth = 1;
con.gridx = 3;
con.gridy = 0;
con.insets = new Insets(5, 5, 5, 5);
con.weightx = 0;
layout.setConstraints(red, con);
con = new GridBagConstraints();
con.gridheight = 1;
con.gridwidth = 1;
con.gridx = 4;
con.gridy = 0;
con.insets = new Insets(5, 5, 5, 5);
con.weightx = 0;
layout.setConstraints(yellow, con);
con = new GridBagConstraints();
con.gridheight = 1;
con.gridwidth = 1;
con.gridx = 5;
con.gridy = 0;
con.weightx = 1;
layout.setConstraints(spacer2, con);
setLayout(layout);
add(spacer1);
add(blue);
add(green);
add(red);
add(yellow);
add(spacer2);
}
}