Add some endOfTurn handling to RoundControl

git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@155 72836036-5685-4462-b002-a69064685172
This commit is contained in:
Matthias Schiffer 2011-05-05 21:13:59 +02:00
parent 0b66e7d763
commit 38f6f0dc24
6 changed files with 254 additions and 219 deletions

View file

@ -6,6 +6,7 @@ import java.util.List;
public class MockGameState implements IGameState { public class MockGameState implements IGameState {
public MockTable table; public MockTable table;
public ITable setTable;
public List<MockPlayer> players; public List<MockPlayer> players;
public int activePlayer; public int activePlayer;
public StoneHeap gameHeap; public StoneHeap gameHeap;
@ -56,4 +57,9 @@ public class MockGameState implements IGameState {
public IPlayer getNthNextPlayer(int i) { public IPlayer getNthNextPlayer(int i) {
return players.get((activePlayer + i) % players.size()); return players.get((activePlayer + i) % players.size());
} }
@Override
public void setTable(ITable table) {
setTable = table;
}
} }

View file

@ -60,6 +60,7 @@ public class RoundControl {
endOfTurn(); endOfTurn();
} }
}); });
turnControl.startTurn(); turnControl.startTurn();
} }
@ -74,7 +75,27 @@ public class RoundControl {
} }
private void endOfTurn() { private void endOfTurn() {
Set<Stone> tableDiff = tableDifference(gameState.getTable(), clonedTable);
if (!tableDiff.isEmpty()) { // Player has made a move
if (clonedTable.isValid()) {
gameState.setTable(clonedTable);
// TODO Win check
} else {
gameState.getGameHeap().putBack(tableDiff);
dealPenalty(tableDiff.size());
}
} else { // Player hasn't made a move
if (clonedTable.isValid()) {
gameState.setTable(clonedTable);
}
dealStone();
}
gameState.nextPlayer();
prepareTurn();
} }
static Set<Stone> tableDifference(ITable oldTable, ITable newTable) { static Set<Stone> tableDifference(ITable oldTable, ITable newTable) {
@ -94,15 +115,12 @@ public class RoundControl {
return ret; return ret;
} }
private void resetTable() {
}
private void preparePlayerTurn() {
}
private void dealStone() { private void dealStone() {
// gameState.getActivePlayer().getHand().drop(object, position)
}
private void dealPenalty(int count) {
for (int i = 0; i < count + 3; ++i)
dealStone();
} }
} }

View file

@ -27,6 +27,11 @@ public class GameState implements IGameState {
return table; return table;
} }
@Override
public void setTable(ITable table) {
this.table = table;
}
@Override @Override
public int getPlayerCount() { public int getPlayerCount() {
return players.size(); return players.size();

View file

@ -3,6 +3,7 @@ package jrummikub.model;
public interface IGameState { public interface IGameState {
public ITable getTable(); public ITable getTable();
public void setTable(ITable table);
public int getPlayerCount(); public int getPlayerCount();

View file

@ -1,6 +1,7 @@
package jrummikub.model; package jrummikub.model;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
@ -42,7 +43,7 @@ public class StoneHeap {
* Removes several {@link Stone}s from the heap and returns them * Removes several {@link Stone}s from the heap and returns them
* *
* @param number * @param number
* number of requested Stones * number of requested Stones
* @return list of drawn stones * @return list of drawn stones
*/ */
public List<Stone> drawStones(int number) { public List<Stone> drawStones(int number) {
@ -56,4 +57,8 @@ public class StoneHeap {
public int getSize() { public int getSize() {
return heap.size(); return heap.size();
} }
public void putBack(Collection<Stone> stones) {
heap.addAll(stones);
}
} }

View file

@ -19,256 +19,256 @@ import jrummikub.model.StoneColor;
* coordinates * coordinates
*/ */
class StonePainter { class StonePainter {
private static final float ASPECT_RATIO = 0.75f; private static final float ASPECT_RATIO = 0.75f;
private static final float DEFAULT_WIDTH = 40; private static final float DEFAULT_WIDTH = 40;
private static final float TEXT_POS = 0.275f; private static final float TEXT_POS = 0.275f;
private static final float FACE_WIDTH = 0.475f; private static final float FACE_WIDTH = 0.475f;
private static final float CIRCLE_POS = 0.725f; private static final float CIRCLE_POS = 0.725f;
private static final float CIRCLE_WIDTH = 0.45f; private static final float CIRCLE_WIDTH = 0.45f;
private static final Color BACKGROUND_COLOR = new Color(0.9f, 0.9f, 0.6f); private static final Color BACKGROUND_COLOR = new Color(0.9f, 0.9f, 0.6f);
private static final Color SELECTED_COLOR = BACKGROUND_COLOR.darker(); private static final Color SELECTED_COLOR = BACKGROUND_COLOR.darker();
private static final float BRIGHTER_SCALE = 1.15f; private static final float BRIGHTER_SCALE = 1.15f;
/** /**
* The width of one pixel in the scale of 1.0 * The width of one pixel in the scale of 1.0
*/ */
public static final float WIDTH_SCALE = 1 / DEFAULT_WIDTH; public static final float WIDTH_SCALE = 1 / DEFAULT_WIDTH;
/** /**
* The height of one pixel in the scale of 1.0 * The height of one pixel in the scale of 1.0
*/ */
public static final float HEIGHT_SCALE = ASPECT_RATIO / DEFAULT_WIDTH; public static final float HEIGHT_SCALE = ASPECT_RATIO / DEFAULT_WIDTH;
private float scale; private float scale;
private static int even(float f) { private static int even(float f) {
return 2 * (int) (f / 2); return 2 * (int) (f / 2);
} }
private static Color brighter(Color color) { private static Color brighter(Color color) {
int r = (int) (color.getRed() * BRIGHTER_SCALE); int r = (int) (color.getRed() * BRIGHTER_SCALE);
int g = (int) (color.getRed() * BRIGHTER_SCALE); int g = (int) (color.getRed() * BRIGHTER_SCALE);
int b = (int) (color.getRed() * BRIGHTER_SCALE); int b = (int) (color.getRed() * BRIGHTER_SCALE);
return new Color(r > 255 ? 255 : r, g > 255 ? 255 : g, b > 255 ? 255 : b); return new Color(r > 255 ? 255 : r, g > 255 ? 255 : g, b > 255 ? 255 : b);
} }
private static Color getColor(StoneColor color) { private static Color getColor(StoneColor color) {
switch (color) { switch (color) {
case BLACK: case BLACK:
return new Color(0.15f, 0.15f, 0.15f); return new Color(0.15f, 0.15f, 0.15f);
case BLUE: case BLUE:
return new Color(0.0f, 0.0f, 1.0f); return new Color(0.0f, 0.0f, 1.0f);
case ORANGE: case ORANGE:
return new Color(1.0f, 0.6f, 0.0f); return new Color(1.0f, 0.6f, 0.0f);
case RED: case RED:
return new Color(0.9f, 0.0f, 0.25f); return new Color(0.9f, 0.0f, 0.25f);
} }
return null; return null;
} }
/** /**
* Sets the new grid scale * Sets the new grid scale
* *
* @param scale * @param scale
* the new scale * the new scale
*/ */
public void setScale(float scale) { public void setScale(float scale) {
this.scale = scale; this.scale = scale;
} }
/** /**
* @return the current grid scale * @return the current grid scale
*/ */
public float getScale() { public float getScale() {
return scale; return scale;
} }
/** /**
* @param x * @param x
* x position in screen coordinates * x position in screen coordinates
* @param y * @param y
* y position in screen coordinates * y position in screen coordinates
* @return position in grid coordinates * @return position in grid coordinates
*/ */
public Position calculatePosition(int x, int y) { public Position calculatePosition(int x, int y) {
float width = getStoneWidth(); float width = getStoneWidth();
float height = getStoneHeight(); float height = getStoneHeight();
return new Position(x / width, y / height); return new Position(x / width, y / height);
} }
/** /**
* @return the width of a stone in the current scale in pixels * @return the width of a stone in the current scale in pixels
*/ */
public int getStoneWidth() { public int getStoneWidth() {
return even(DEFAULT_WIDTH * scale); return even(DEFAULT_WIDTH * scale);
} }
/** /**
* @return the height of a stone in the current scale in pixels * @return the height of a stone in the current scale in pixels
*/ */
public int getStoneHeight() { public int getStoneHeight() {
return (int) (DEFAULT_WIDTH * scale / ASPECT_RATIO); return (int) (DEFAULT_WIDTH * scale / ASPECT_RATIO);
} }
/** /**
* @param scale * @param scale
* the scaling factor for the grid coordinates * the scaling factor for the grid coordinates
*/ */
StonePainter(float scale) { StonePainter(float scale) {
this.scale = scale; this.scale = scale;
} }
private void paintStoneBackground(Graphics2D g, Rectangle r, Color background) { private void paintStoneBackground(Graphics2D g, Rectangle r, Color background) {
// Paint background // Paint background
g.setColor(background); g.setColor(background);
g.fillRect(r.x, r.y, r.width, r.height); g.fillRect(r.x, r.y, r.width, r.height);
// Paint bevel border // Paint bevel border
g.setColor(brighter(brighter(background))); g.setColor(brighter(brighter(background)));
g.fillRect(r.x, r.y, 1, r.height); g.fillRect(r.x, r.y, 1, r.height);
g.setColor(brighter(background)); g.setColor(brighter(background));
g.fillRect(r.x + 1, r.y + 1, 1, r.height - 2); g.fillRect(r.x + 1, r.y + 1, 1, r.height - 2);
g.setColor(brighter(brighter(background))); g.setColor(brighter(brighter(background)));
g.fillRect(r.x, r.y, r.width, 1); g.fillRect(r.x, r.y, r.width, 1);
g.setColor(brighter(background)); g.setColor(brighter(background));
g.fillRect(r.x + 1, r.y + 1, r.width - 2, 1); g.fillRect(r.x + 1, r.y + 1, r.width - 2, 1);
g.setColor(background.darker().darker()); g.setColor(background.darker().darker());
g.fillRect(r.x + r.width - 1, r.y, 1, r.height); g.fillRect(r.x + r.width - 1, r.y, 1, r.height);
g.setColor(background.darker()); g.setColor(background.darker());
g.fillRect(r.x + r.width - 2, r.y + 1, 1, r.height - 2); g.fillRect(r.x + r.width - 2, r.y + 1, 1, r.height - 2);
g.setColor(background.darker().darker()); g.setColor(background.darker().darker());
g.fillRect(r.x, r.y + r.height - 1, r.width, 1); g.fillRect(r.x, r.y + r.height - 1, r.width, 1);
g.setColor(background.darker()); g.setColor(background.darker());
g.fillRect(r.x + 1, r.y + r.height - 2, r.width - 2, 1); g.fillRect(r.x + 1, r.y + r.height - 2, r.width - 2, 1);
} }
private void paintJokerFace(Graphics2D g, Rectangle r) { private void paintJokerFace(Graphics2D g, Rectangle r) {
Stroke oldStroke = g.getStroke(); Stroke oldStroke = g.getStroke();
g.setStroke(new BasicStroke(2)); g.setStroke(new BasicStroke(2));
g.drawOval(r.x, r.y, r.width, r.height); g.drawOval(r.x, r.y, r.width, r.height);
g.setStroke(new BasicStroke(1)); g.setStroke(new BasicStroke(1));
GeneralPath path = new GeneralPath(); GeneralPath path = new GeneralPath();
// nose // nose
path.moveTo(r.x + 0.5f * r.width, r.y + 0.45f * r.height); path.moveTo(r.x + 0.5f * r.width, r.y + 0.45f * r.height);
path.lineTo(r.x + 0.53f * r.width, r.y + 0.6f * r.height); path.lineTo(r.x + 0.53f * r.width, r.y + 0.6f * r.height);
path.lineTo(r.x + 0.47f * r.width, r.y + 0.6f * r.height); path.lineTo(r.x + 0.47f * r.width, r.y + 0.6f * r.height);
path.closePath(); path.closePath();
g.fill(path); g.fill(path);
path.reset(); path.reset();
// mouth, left // mouth, left
path.moveTo(r.x + 0.23f * r.width, r.y + 0.75f * r.width); path.moveTo(r.x + 0.23f * r.width, r.y + 0.75f * r.width);
path.lineTo(r.x + 0.27f * r.width, r.y + 0.65f * r.width); path.lineTo(r.x + 0.27f * r.width, r.y + 0.65f * r.width);
// mouth, middle // mouth, middle
path.moveTo(r.x + 0.25f * r.width, r.y + 0.7f * r.width); path.moveTo(r.x + 0.25f * r.width, r.y + 0.7f * r.width);
path.lineTo(r.x + 0.5f * r.width, r.y + 0.8f * r.width); path.lineTo(r.x + 0.5f * r.width, r.y + 0.8f * r.width);
path.lineTo(r.x + 0.75f * r.width, r.y + 0.7f * r.width); path.lineTo(r.x + 0.75f * r.width, r.y + 0.7f * r.width);
// mouth, right // mouth, right
path.moveTo(r.x + 0.77f * r.width, r.y + 0.75f * r.width); path.moveTo(r.x + 0.77f * r.width, r.y + 0.75f * r.width);
path.lineTo(r.x + 0.73f * r.width, r.y + 0.65f * r.width); path.lineTo(r.x + 0.73f * r.width, r.y + 0.65f * r.width);
g.draw(path); g.draw(path);
path.reset(); path.reset();
// left eye // left eye
path.moveTo(r.x + 0.3f * r.width, r.y + 0.41f * r.height); path.moveTo(r.x + 0.3f * r.width, r.y + 0.41f * r.height);
path.lineTo(r.x + 0.375f * r.width, r.y + 0.375f * r.height); path.lineTo(r.x + 0.375f * r.width, r.y + 0.375f * r.height);
path.lineTo(r.x + 0.3f * r.width, r.y + 0.34f * r.height); path.lineTo(r.x + 0.3f * r.width, r.y + 0.34f * r.height);
path.lineTo(r.x + 0.225f * r.width, r.y + 0.375f * r.height); path.lineTo(r.x + 0.225f * r.width, r.y + 0.375f * r.height);
path.closePath(); path.closePath();
g.draw(path); g.draw(path);
path.reset(); path.reset();
// right eye // right eye
path.moveTo(r.x + 0.7f * r.width, r.y + 0.41f * r.height); path.moveTo(r.x + 0.7f * r.width, r.y + 0.41f * r.height);
path.lineTo(r.x + 0.625f * r.width, r.y + 0.375f * r.height); path.lineTo(r.x + 0.625f * r.width, r.y + 0.375f * r.height);
path.lineTo(r.x + 0.7f * r.width, r.y + 0.34f * r.height); path.lineTo(r.x + 0.7f * r.width, r.y + 0.34f * r.height);
path.lineTo(r.x + 0.775f * r.width, r.y + 0.375f * r.height); path.lineTo(r.x + 0.775f * r.width, r.y + 0.375f * r.height);
path.closePath(); path.closePath();
g.draw(path); g.draw(path);
g.setStroke(oldStroke); g.setStroke(oldStroke);
} }
private void paintJoker(Graphics2D g, Rectangle r, Color color) { private void paintJoker(Graphics2D g, Rectangle r, Color color) {
int faceSize = even(FACE_WIDTH * r.width); int faceSize = even(FACE_WIDTH * r.width);
int pos = r.y + (int) (TEXT_POS * r.height); int pos = r.y + (int) (TEXT_POS * r.height);
g.setColor(color); g.setColor(color);
paintJokerFace(g, new Rectangle(r.x + r.width / 2 - faceSize / 2, pos paintJokerFace(g, new Rectangle(r.x + r.width / 2 - faceSize / 2, pos
- faceSize / 2, faceSize, faceSize)); - faceSize / 2, faceSize, faceSize));
} }
private void paintStoneValue(Graphics2D g, Rectangle r, Color color, int v) { private void paintStoneValue(Graphics2D g, Rectangle r, Color color, int v) {
int pos = r.y + (int) (TEXT_POS * r.height); int pos = r.y + (int) (TEXT_POS * r.height);
g.setFont(new Font("SansSerif", Font.BOLD, r.height / 4)); g.setFont(new Font("SansSerif", Font.BOLD, r.height / 4));
FontMetrics fm = g.getFontMetrics(); FontMetrics fm = g.getFontMetrics();
String value = Integer.toString(v); String value = Integer.toString(v);
Rectangle2D stringRect = fm.getStringBounds(value, g); Rectangle2D stringRect = fm.getStringBounds(value, g);
g.setColor(color.darker()); g.setColor(color.darker());
g.drawString(value, g.drawString(value,
(int) (r.x + r.width / 2 - stringRect.getWidth() / 2) + 1, (int) (r.x + r.width / 2 - stringRect.getWidth() / 2) + 1,
pos + (fm.getAscent() - fm.getDescent()) / 2 + 1); pos + (fm.getAscent() - fm.getDescent()) / 2 + 1);
g.setColor(color); g.setColor(color);
g.drawString(value, (int) (r.x + r.width / 2 - stringRect.getWidth() / 2), g.drawString(value, (int) (r.x + r.width / 2 - stringRect.getWidth() / 2),
pos + (fm.getAscent() - fm.getDescent()) / 2); pos + (fm.getAscent() - fm.getDescent()) / 2);
} }
private void paintCircle(Graphics2D g, Rectangle r, Color background) { private void paintCircle(Graphics2D g, Rectangle r, Color background) {
int size = even(r.width * CIRCLE_WIDTH); int size = even(r.width * CIRCLE_WIDTH);
int pos = r.y + (int) (CIRCLE_POS * r.height); int pos = r.y + (int) (CIRCLE_POS * r.height);
// Paint circle // Paint circle
g.setColor(background.darker()); g.setColor(background.darker());
g.drawArc(r.x + r.width / 2 - size / 2, pos - size / 2, size, size, 50, 170); g.drawArc(r.x + r.width / 2 - size / 2, pos - size / 2, size, size, 50, 170);
g.setColor(brighter(background)); g.setColor(brighter(background));
g.drawArc((int) (r.x + r.width / 2 - size / 2), pos - size / 2, size, size, g.drawArc((int) (r.x + r.width / 2 - size / 2), pos - size / 2, size, size,
-130, 170); -130, 170);
} }
/** /**
* Paints a stone * Paints a stone
* *
* @param g * @param g
* the graphics context to paint the stone on * the graphics context to paint the stone on
* @param stone * @param stone
* the stone to paint * the stone to paint
* @param p * @param p
* the position of the stone * the position of the stone
* @param selected * @param selected
* if selected is true the stone will be painted darker * if selected is true the stone will be painted darker
*/ */
public void paintStone(Graphics2D g, Stone stone, Position p, boolean selected) { public void paintStone(Graphics2D g, Stone stone, Position p, boolean selected) {
Color background = selected ? SELECTED_COLOR : BACKGROUND_COLOR; Color background = selected ? SELECTED_COLOR : BACKGROUND_COLOR;
int width = getStoneWidth(); int width = getStoneWidth();
int height = getStoneHeight(); int height = getStoneHeight();
Rectangle rect = new Rectangle((int) (p.getX() * width), Rectangle rect = new Rectangle((int) (p.getX() * width),
(int) (p.getY() * height), width, height); (int) (p.getY() * height), width, height);
paintStoneBackground(g, rect, background); paintStoneBackground(g, rect, background);
Color color = getColor(stone.getColor()); Color color = getColor(stone.getColor());
if (selected) if (selected)
color = color.darker(); color = color.darker();
if (stone.isJoker()) { if (stone.isJoker()) {
paintJoker(g, rect, color); paintJoker(g, rect, color);
} else { } else {
paintStoneValue(g, rect, color, stone.getValue()); paintStoneValue(g, rect, color, stone.getValue());
} }
paintCircle(g, rect, background); paintCircle(g, rect, background);
} }
} }