summaryrefslogtreecommitdiffstats
path: root/src/jrummikub
diff options
context:
space:
mode:
Diffstat (limited to 'src/jrummikub')
-rw-r--r--src/jrummikub/control/RoundControl.java34
-rw-r--r--src/jrummikub/model/GameState.java5
-rw-r--r--src/jrummikub/model/IGameState.java1
-rw-r--r--src/jrummikub/model/StoneHeap.java7
-rw-r--r--src/jrummikub/view/impl/StonePainter.java504
5 files changed, 290 insertions, 261 deletions
diff --git a/src/jrummikub/control/RoundControl.java b/src/jrummikub/control/RoundControl.java
index 8f8180d..00ebb6e 100644
--- a/src/jrummikub/control/RoundControl.java
+++ b/src/jrummikub/control/RoundControl.java
@@ -60,6 +60,7 @@ public class RoundControl {
endOfTurn();
}
});
+
turnControl.startTurn();
}
@@ -74,7 +75,27 @@ public class RoundControl {
}
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) {
@@ -94,15 +115,12 @@ public class RoundControl {
return ret;
}
- private void resetTable() {
-
- }
-
- private void preparePlayerTurn() {
-
- }
-
private void dealStone() {
+ // gameState.getActivePlayer().getHand().drop(object, position)
+ }
+ private void dealPenalty(int count) {
+ for (int i = 0; i < count + 3; ++i)
+ dealStone();
}
}
diff --git a/src/jrummikub/model/GameState.java b/src/jrummikub/model/GameState.java
index 0539ea0..d9f18b3 100644
--- a/src/jrummikub/model/GameState.java
+++ b/src/jrummikub/model/GameState.java
@@ -28,6 +28,11 @@ public class GameState implements IGameState {
}
@Override
+ public void setTable(ITable table) {
+ this.table = table;
+ }
+
+ @Override
public int getPlayerCount() {
return players.size();
}
diff --git a/src/jrummikub/model/IGameState.java b/src/jrummikub/model/IGameState.java
index 46ea0b0..df98a2c 100644
--- a/src/jrummikub/model/IGameState.java
+++ b/src/jrummikub/model/IGameState.java
@@ -3,6 +3,7 @@ package jrummikub.model;
public interface IGameState {
public ITable getTable();
+ public void setTable(ITable table);
public int getPlayerCount();
diff --git a/src/jrummikub/model/StoneHeap.java b/src/jrummikub/model/StoneHeap.java
index 42cb01e..ae84cef 100644
--- a/src/jrummikub/model/StoneHeap.java
+++ b/src/jrummikub/model/StoneHeap.java
@@ -1,6 +1,7 @@
package jrummikub.model;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Random;
@@ -42,7 +43,7 @@ public class StoneHeap {
* Removes several {@link Stone}s from the heap and returns them
*
* @param number
- * number of requested Stones
+ * number of requested Stones
* @return list of drawn stones
*/
public List<Stone> drawStones(int number) {
@@ -56,4 +57,8 @@ public class StoneHeap {
public int getSize() {
return heap.size();
}
+
+ public void putBack(Collection<Stone> stones) {
+ heap.addAll(stones);
+ }
}
diff --git a/src/jrummikub/view/impl/StonePainter.java b/src/jrummikub/view/impl/StonePainter.java
index b901e78..0700966 100644
--- a/src/jrummikub/view/impl/StonePainter.java
+++ b/src/jrummikub/view/impl/StonePainter.java
@@ -19,256 +19,256 @@ import jrummikub.model.StoneColor;
* coordinates
*/
class StonePainter {
- private static final float ASPECT_RATIO = 0.75f;
- private static final float DEFAULT_WIDTH = 40;
- private static final float TEXT_POS = 0.275f;
- private static final float FACE_WIDTH = 0.475f;
- private static final float CIRCLE_POS = 0.725f;
- 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 SELECTED_COLOR = BACKGROUND_COLOR.darker();
-
- private static final float BRIGHTER_SCALE = 1.15f;
-
- /**
- * The width of one pixel in the scale of 1.0
- */
- public static final float WIDTH_SCALE = 1 / DEFAULT_WIDTH;
- /**
- * The height of one pixel in the scale of 1.0
- */
- public static final float HEIGHT_SCALE = ASPECT_RATIO / DEFAULT_WIDTH;
-
- private float scale;
-
- private static int even(float f) {
- return 2 * (int) (f / 2);
- }
-
- private static Color brighter(Color color) {
- int r = (int) (color.getRed() * BRIGHTER_SCALE);
- int g = (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);
- }
-
- private static Color getColor(StoneColor color) {
- switch (color) {
- case BLACK:
- return new Color(0.15f, 0.15f, 0.15f);
- case BLUE:
- return new Color(0.0f, 0.0f, 1.0f);
- case ORANGE:
- return new Color(1.0f, 0.6f, 0.0f);
- case RED:
- return new Color(0.9f, 0.0f, 0.25f);
- }
-
- return null;
- }
-
- /**
- * Sets the new grid scale
- *
- * @param scale
- * the new scale
- */
- public void setScale(float scale) {
- this.scale = scale;
- }
-
- /**
- * @return the current grid scale
- */
- public float getScale() {
- return scale;
- }
-
- /**
- * @param x
- * x position in screen coordinates
- * @param y
- * y position in screen coordinates
- * @return position in grid coordinates
- */
- public Position calculatePosition(int x, int y) {
- float width = getStoneWidth();
- float height = getStoneHeight();
-
- return new Position(x / width, y / height);
- }
-
- /**
- * @return the width of a stone in the current scale in pixels
- */
- public int getStoneWidth() {
- return even(DEFAULT_WIDTH * scale);
- }
-
- /**
- * @return the height of a stone in the current scale in pixels
- */
- public int getStoneHeight() {
- return (int) (DEFAULT_WIDTH * scale / ASPECT_RATIO);
- }
-
- /**
- * @param scale
- * the scaling factor for the grid coordinates
- */
- StonePainter(float scale) {
- this.scale = scale;
- }
-
- private void paintStoneBackground(Graphics2D g, Rectangle r, Color background) {
- // Paint background
- g.setColor(background);
- g.fillRect(r.x, r.y, r.width, r.height);
-
- // Paint bevel border
- g.setColor(brighter(brighter(background)));
- g.fillRect(r.x, r.y, 1, r.height);
- g.setColor(brighter(background));
- g.fillRect(r.x + 1, r.y + 1, 1, r.height - 2);
-
- g.setColor(brighter(brighter(background)));
- g.fillRect(r.x, r.y, r.width, 1);
- g.setColor(brighter(background));
- g.fillRect(r.x + 1, r.y + 1, r.width - 2, 1);
-
- g.setColor(background.darker().darker());
- g.fillRect(r.x + r.width - 1, r.y, 1, r.height);
- g.setColor(background.darker());
- g.fillRect(r.x + r.width - 2, r.y + 1, 1, r.height - 2);
-
- g.setColor(background.darker().darker());
- g.fillRect(r.x, r.y + r.height - 1, r.width, 1);
- g.setColor(background.darker());
- g.fillRect(r.x + 1, r.y + r.height - 2, r.width - 2, 1);
- }
-
- private void paintJokerFace(Graphics2D g, Rectangle r) {
- Stroke oldStroke = g.getStroke();
-
- g.setStroke(new BasicStroke(2));
- g.drawOval(r.x, r.y, r.width, r.height);
-
- g.setStroke(new BasicStroke(1));
- GeneralPath path = new GeneralPath();
- // nose
- 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.47f * r.width, r.y + 0.6f * r.height);
- path.closePath();
- g.fill(path);
-
- path.reset();
- // mouth, left
- 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);
- // mouth, middle
- 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.75f * r.width, r.y + 0.7f * r.width);
- // mouth, right
- 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);
- g.draw(path);
-
- path.reset();
- // left eye
- 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.3f * r.width, r.y + 0.34f * r.height);
- path.lineTo(r.x + 0.225f * r.width, r.y + 0.375f * r.height);
- path.closePath();
- g.draw(path);
-
- path.reset();
- // right eye
- 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.7f * r.width, r.y + 0.34f * r.height);
- path.lineTo(r.x + 0.775f * r.width, r.y + 0.375f * r.height);
- path.closePath();
- g.draw(path);
-
- g.setStroke(oldStroke);
- }
-
- private void paintJoker(Graphics2D g, Rectangle r, Color color) {
- int faceSize = even(FACE_WIDTH * r.width);
- int pos = r.y + (int) (TEXT_POS * r.height);
-
- g.setColor(color);
- paintJokerFace(g, new Rectangle(r.x + r.width / 2 - faceSize / 2, pos
- - faceSize / 2, faceSize, faceSize));
- }
-
- private void paintStoneValue(Graphics2D g, Rectangle r, Color color, int v) {
- int pos = r.y + (int) (TEXT_POS * r.height);
-
- g.setFont(new Font("SansSerif", Font.BOLD, r.height / 4));
- FontMetrics fm = g.getFontMetrics();
- String value = Integer.toString(v);
- Rectangle2D stringRect = fm.getStringBounds(value, g);
-
- g.setColor(color.darker());
- g.drawString(value,
- (int) (r.x + r.width / 2 - stringRect.getWidth() / 2) + 1,
- pos + (fm.getAscent() - fm.getDescent()) / 2 + 1);
- g.setColor(color);
- g.drawString(value, (int) (r.x + r.width / 2 - stringRect.getWidth() / 2),
- pos + (fm.getAscent() - fm.getDescent()) / 2);
- }
-
- private void paintCircle(Graphics2D g, Rectangle r, Color background) {
- int size = even(r.width * CIRCLE_WIDTH);
- int pos = r.y + (int) (CIRCLE_POS * r.height);
-
- // Paint circle
- g.setColor(background.darker());
- g.drawArc(r.x + r.width / 2 - size / 2, pos - size / 2, size, size, 50, 170);
-
- g.setColor(brighter(background));
- g.drawArc((int) (r.x + r.width / 2 - size / 2), pos - size / 2, size, size,
- -130, 170);
- }
-
- /**
- * Paints a stone
- *
- * @param g
- * the graphics context to paint the stone on
- * @param stone
- * the stone to paint
- * @param p
- * the position of the stone
- * @param selected
- * if selected is true the stone will be painted darker
- */
- public void paintStone(Graphics2D g, Stone stone, Position p, boolean selected) {
- Color background = selected ? SELECTED_COLOR : BACKGROUND_COLOR;
- int width = getStoneWidth();
- int height = getStoneHeight();
-
- Rectangle rect = new Rectangle((int) (p.getX() * width),
- (int) (p.getY() * height), width, height);
-
- paintStoneBackground(g, rect, background);
-
- Color color = getColor(stone.getColor());
- if (selected)
- color = color.darker();
-
- if (stone.isJoker()) {
- paintJoker(g, rect, color);
- } else {
- paintStoneValue(g, rect, color, stone.getValue());
- }
-
- paintCircle(g, rect, background);
- }
+ private static final float ASPECT_RATIO = 0.75f;
+ private static final float DEFAULT_WIDTH = 40;
+ private static final float TEXT_POS = 0.275f;
+ private static final float FACE_WIDTH = 0.475f;
+ private static final float CIRCLE_POS = 0.725f;
+ 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 SELECTED_COLOR = BACKGROUND_COLOR.darker();
+
+ private static final float BRIGHTER_SCALE = 1.15f;
+
+ /**
+ * The width of one pixel in the scale of 1.0
+ */
+ public static final float WIDTH_SCALE = 1 / DEFAULT_WIDTH;
+ /**
+ * The height of one pixel in the scale of 1.0
+ */
+ public static final float HEIGHT_SCALE = ASPECT_RATIO / DEFAULT_WIDTH;
+
+ private float scale;
+
+ private static int even(float f) {
+ return 2 * (int) (f / 2);
+ }
+
+ private static Color brighter(Color color) {
+ int r = (int) (color.getRed() * BRIGHTER_SCALE);
+ int g = (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);
+ }
+
+ private static Color getColor(StoneColor color) {
+ switch (color) {
+ case BLACK:
+ return new Color(0.15f, 0.15f, 0.15f);
+ case BLUE:
+ return new Color(0.0f, 0.0f, 1.0f);
+ case ORANGE:
+ return new Color(1.0f, 0.6f, 0.0f);
+ case RED:
+ return new Color(0.9f, 0.0f, 0.25f);
+ }
+
+ return null;
+ }
+
+ /**
+ * Sets the new grid scale
+ *
+ * @param scale
+ * the new scale
+ */
+ public void setScale(float scale) {
+ this.scale = scale;
+ }
+
+ /**
+ * @return the current grid scale
+ */
+ public float getScale() {
+ return scale;
+ }
+
+ /**
+ * @param x
+ * x position in screen coordinates
+ * @param y
+ * y position in screen coordinates
+ * @return position in grid coordinates
+ */
+ public Position calculatePosition(int x, int y) {
+ float width = getStoneWidth();
+ float height = getStoneHeight();
+
+ return new Position(x / width, y / height);
+ }
+
+ /**
+ * @return the width of a stone in the current scale in pixels
+ */
+ public int getStoneWidth() {
+ return even(DEFAULT_WIDTH * scale);
+ }
+
+ /**
+ * @return the height of a stone in the current scale in pixels
+ */
+ public int getStoneHeight() {
+ return (int) (DEFAULT_WIDTH * scale / ASPECT_RATIO);
+ }
+
+ /**
+ * @param scale
+ * the scaling factor for the grid coordinates
+ */
+ StonePainter(float scale) {
+ this.scale = scale;
+ }
+
+ private void paintStoneBackground(Graphics2D g, Rectangle r, Color background) {
+ // Paint background
+ g.setColor(background);
+ g.fillRect(r.x, r.y, r.width, r.height);
+
+ // Paint bevel border
+ g.setColor(brighter(brighter(background)));
+ g.fillRect(r.x, r.y, 1, r.height);
+ g.setColor(brighter(background));
+ g.fillRect(r.x + 1, r.y + 1, 1, r.height - 2);
+
+ g.setColor(brighter(brighter(background)));
+ g.fillRect(r.x, r.y, r.width, 1);
+ g.setColor(brighter(background));
+ g.fillRect(r.x + 1, r.y + 1, r.width - 2, 1);
+
+ g.setColor(background.darker().darker());
+ g.fillRect(r.x + r.width - 1, r.y, 1, r.height);
+ g.setColor(background.darker());
+ g.fillRect(r.x + r.width - 2, r.y + 1, 1, r.height - 2);
+
+ g.setColor(background.darker().darker());
+ g.fillRect(r.x, r.y + r.height - 1, r.width, 1);
+ g.setColor(background.darker());
+ g.fillRect(r.x + 1, r.y + r.height - 2, r.width - 2, 1);
+ }
+
+ private void paintJokerFace(Graphics2D g, Rectangle r) {
+ Stroke oldStroke = g.getStroke();
+
+ g.setStroke(new BasicStroke(2));
+ g.drawOval(r.x, r.y, r.width, r.height);
+
+ g.setStroke(new BasicStroke(1));
+ GeneralPath path = new GeneralPath();
+ // nose
+ 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.47f * r.width, r.y + 0.6f * r.height);
+ path.closePath();
+ g.fill(path);
+
+ path.reset();
+ // mouth, left
+ 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);
+ // mouth, middle
+ 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.75f * r.width, r.y + 0.7f * r.width);
+ // mouth, right
+ 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);
+ g.draw(path);
+
+ path.reset();
+ // left eye
+ 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.3f * r.width, r.y + 0.34f * r.height);
+ path.lineTo(r.x + 0.225f * r.width, r.y + 0.375f * r.height);
+ path.closePath();
+ g.draw(path);
+
+ path.reset();
+ // right eye
+ 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.7f * r.width, r.y + 0.34f * r.height);
+ path.lineTo(r.x + 0.775f * r.width, r.y + 0.375f * r.height);
+ path.closePath();
+ g.draw(path);
+
+ g.setStroke(oldStroke);
+ }
+
+ private void paintJoker(Graphics2D g, Rectangle r, Color color) {
+ int faceSize = even(FACE_WIDTH * r.width);
+ int pos = r.y + (int) (TEXT_POS * r.height);
+
+ g.setColor(color);
+ paintJokerFace(g, new Rectangle(r.x + r.width / 2 - faceSize / 2, pos
+ - faceSize / 2, faceSize, faceSize));
+ }
+
+ private void paintStoneValue(Graphics2D g, Rectangle r, Color color, int v) {
+ int pos = r.y + (int) (TEXT_POS * r.height);
+
+ g.setFont(new Font("SansSerif", Font.BOLD, r.height / 4));
+ FontMetrics fm = g.getFontMetrics();
+ String value = Integer.toString(v);
+ Rectangle2D stringRect = fm.getStringBounds(value, g);
+
+ g.setColor(color.darker());
+ g.drawString(value,
+ (int) (r.x + r.width / 2 - stringRect.getWidth() / 2) + 1,
+ pos + (fm.getAscent() - fm.getDescent()) / 2 + 1);
+ g.setColor(color);
+ g.drawString(value, (int) (r.x + r.width / 2 - stringRect.getWidth() / 2),
+ pos + (fm.getAscent() - fm.getDescent()) / 2);
+ }
+
+ private void paintCircle(Graphics2D g, Rectangle r, Color background) {
+ int size = even(r.width * CIRCLE_WIDTH);
+ int pos = r.y + (int) (CIRCLE_POS * r.height);
+
+ // Paint circle
+ g.setColor(background.darker());
+ g.drawArc(r.x + r.width / 2 - size / 2, pos - size / 2, size, size, 50, 170);
+
+ g.setColor(brighter(background));
+ g.drawArc((int) (r.x + r.width / 2 - size / 2), pos - size / 2, size, size,
+ -130, 170);
+ }
+
+ /**
+ * Paints a stone
+ *
+ * @param g
+ * the graphics context to paint the stone on
+ * @param stone
+ * the stone to paint
+ * @param p
+ * the position of the stone
+ * @param selected
+ * if selected is true the stone will be painted darker
+ */
+ public void paintStone(Graphics2D g, Stone stone, Position p, boolean selected) {
+ Color background = selected ? SELECTED_COLOR : BACKGROUND_COLOR;
+ int width = getStoneWidth();
+ int height = getStoneHeight();
+
+ Rectangle rect = new Rectangle((int) (p.getX() * width),
+ (int) (p.getY() * height), width, height);
+
+ paintStoneBackground(g, rect, background);
+
+ Color color = getColor(stone.getColor());
+ if (selected)
+ color = color.darker();
+
+ if (stone.isJoker()) {
+ paintJoker(g, rect, color);
+ } else {
+ paintStoneValue(g, rect, color, stone.getValue());
+ }
+
+ paintCircle(g, rect, background);
+ }
}