From af68db873cbece0aeebcfa000a1756eb8657f475 Mon Sep 17 00:00:00 2001 From: Cagdas Date: Wed, 18 Nov 2020 21:47:13 +0300 Subject: [PATCH 1/9] Add mvn exec:java target --- README.md | 6 ++++++ pom.xml | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/README.md b/README.md index c2c0ff8..68885d3 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,12 @@ You will need a Java JDK 8+ and maven 3+. Execute **mvn clean package assembly:single** to build the release package. +# How to run it ? + +**mvn clean** +**mvn package** +**mvn exec:java** + ## How to play ? - SPACE - Start a new game diff --git a/pom.xml b/pom.xml index c8fd6d0..9e992f8 100644 --- a/pom.xml +++ b/pom.xml @@ -111,6 +111,14 @@ @{project.version} + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + spypunk.tetris.Main + + From 80665808fc63a4f0bced13ba191fdce07c8709b1 Mon Sep 17 00:00:00 2001 From: Cagdas Date: Wed, 18 Nov 2020 21:54:18 +0300 Subject: [PATCH 2/9] Update jdk14 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9bcf999..42fe87f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,3 @@ language: java jdk: - - oraclejdk8 + - oraclejdk14 From b8dcec0e5eaf46124a2fb33d0b21307ea1f0daaa Mon Sep 17 00:00:00 2001 From: Caglayan Demirci Date: Tue, 15 Dec 2020 14:31:26 +0300 Subject: [PATCH 3/9] add/implement achievements --- .gitignore | 2 + .../java/spypunk/tetris/model/Tetris.java | 33 ++++++++ .../spypunk/tetris/model/TetrisInstance.java | 44 +++++++++- .../tetris/service/TetrisServiceImpl.java | 23 ++++++ .../ui/view/TetrisAchievementsView.java | 82 +++++++++++++++++++ .../tetris/ui/view/TetrisGridView.java | 3 + .../tetris/ui/view/TetrisInfoView.java | 13 ++- .../tetris/ui/view/TetrisMainViewImpl.java | 2 + 8 files changed, 195 insertions(+), 7 deletions(-) create mode 100644 src/main/java/spypunk/tetris/ui/view/TetrisAchievementsView.java diff --git a/.gitignore b/.gitignore index 18e48c8..6438204 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ hs_err_pid* /.project /.settings/ /tetris.log +.idea +tetris.iml diff --git a/src/main/java/spypunk/tetris/model/Tetris.java b/src/main/java/spypunk/tetris/model/Tetris.java index a97bf3e..eba69bd 100644 --- a/src/main/java/spypunk/tetris/model/Tetris.java +++ b/src/main/java/spypunk/tetris/model/Tetris.java @@ -10,6 +10,7 @@ import java.awt.Point; import java.net.URI; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Optional; @@ -137,6 +138,38 @@ public void setCompletedRows(final int completedRows) { tetrisInstance.setCompletedRows(completedRows); } + public int getAchievementCount() { + return tetrisInstance.getAchievementCount(); + } + + public void setAchievementCount(final int achievementCount) { + tetrisInstance.setAchievementCount(achievementCount); + } + + public ArrayList getAchievements() { + return tetrisInstance.getAchievements(); + } + + public void addAchievement(String achievement) { + tetrisInstance.addAchievement(achievement); + } + + public boolean isRowAbove25() { + return tetrisInstance.IsRowAbove25(); + } + + public void setRowAbove25() { + tetrisInstance.setRowAbove25(); + } + + public boolean isScoreAbove1000() { + return tetrisInstance.IsScoreAbove1000(); + } + + public void setScoreAbove1000() { + tetrisInstance.setScoreAbove1000(); + } + public int getSpeed() { return tetrisInstance.getSpeed(); } diff --git a/src/main/java/spypunk/tetris/model/TetrisInstance.java b/src/main/java/spypunk/tetris/model/TetrisInstance.java index 4cd3199..172fc7b 100644 --- a/src/main/java/spypunk/tetris/model/TetrisInstance.java +++ b/src/main/java/spypunk/tetris/model/TetrisInstance.java @@ -9,10 +9,7 @@ package spypunk.tetris.model; import java.awt.Point; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -44,6 +41,14 @@ public class TetrisInstance { private int completedRows; + private int achievementCount; + + private ArrayList achievements = new ArrayList<>(); + + private boolean rowAbove25 = false; + + private boolean scoreAbove1000 = false; + private int speed; private int currentGravityFrame; @@ -103,6 +108,37 @@ public int getScore() { return score; } + public int getAchievementCount() { + return achievementCount; + } + + public void setAchievementCount(int achievementCount) { + this.achievementCount = achievementCount; + } + + public boolean IsRowAbove25() { + return rowAbove25; + } + public void setRowAbove25() { + this.rowAbove25 = !this.rowAbove25; + } + + public boolean IsScoreAbove1000() { + return scoreAbove1000; + } + + public void setScoreAbove1000() { + this.scoreAbove1000 = !this.scoreAbove1000; + } + + public ArrayList getAchievements() { + return achievements; + } + + public void addAchievement(String achievement) { + this.achievements.add(achievement); + } + public void setScore(final int score) { this.score = score; } diff --git a/src/main/java/spypunk/tetris/service/TetrisServiceImpl.java b/src/main/java/spypunk/tetris/service/TetrisServiceImpl.java index 7b14c0e..fcdcd30 100644 --- a/src/main/java/spypunk/tetris/service/TetrisServiceImpl.java +++ b/src/main/java/spypunk/tetris/service/TetrisServiceImpl.java @@ -193,6 +193,7 @@ private void updateStatistics() { final Integer count = statistics.get(shapeType); statistics.put(shapeType, count + 1); + updateAchievements(); } private boolean isGameOver() { @@ -259,6 +260,28 @@ private void clearCompleteRow(final int row) { blocksToMoveDown.forEach(this::moveBlockDown); } + private void updateAchievements() { + int currentScore = tetris.getScore(), + currentRow = tetris.getCompletedRows(); + boolean scoreIsAbove1000 = false, + rowsIsAbove50 = false; + + if (!tetris.isScoreAbove1000() && currentScore >= 1000) { + updateAchievementCount(); + tetris.addAchievement("YOU REACHED SCORE 1000!"); + tetris.setScoreAbove1000(); + } + if (!tetris.isRowAbove25() && currentRow >= 25) { + updateAchievementCount(); + tetris.addAchievement("YOU HAVE DESTROYED 25 ROWS!"); + tetris.setRowAbove25(); + } + } + + private void updateAchievementCount() { + tetris.setAchievementCount(tetris.getAchievementCount() + 1); + } + private void clearBlockAt(final Point location) { tetris.getBlocks().remove(location); } diff --git a/src/main/java/spypunk/tetris/ui/view/TetrisAchievementsView.java b/src/main/java/spypunk/tetris/ui/view/TetrisAchievementsView.java new file mode 100644 index 0000000..457b5af --- /dev/null +++ b/src/main/java/spypunk/tetris/ui/view/TetrisAchievementsView.java @@ -0,0 +1,82 @@ +/* + * Copyright © 2016-2017 spypunk + * + * This work is free. You can redistribute it and/or modify it under the + * terms of the Do What The Fuck You Want To Public License, Version 2, + * as published by Sam Hocevar. See the COPYING file for more details. + */ + +package spypunk.tetris.ui.view; + +import static spypunk.tetris.ui.constants.TetrisUIConstants.BLOCK_SIZE; + +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Rectangle; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import spypunk.tetris.model.ShapeType; +import spypunk.tetris.model.Tetris; +import spypunk.tetris.ui.cache.ImageCache; +import spypunk.tetris.ui.font.cache.FontCache; +import spypunk.tetris.ui.util.SwingUtils; +import spypunk.tetris.ui.util.SwingUtils.Text; + +public class TetrisAchievementsView extends AbstractTetrisView { + + private static final String ACHOEVEMENTS = "ACHIEVEMENTS"; + + private final Rectangle AchievementsRectangle; + + private final Text AchievementsTitleText; + + private class TetrisAchievement { + + private final Rectangle textRectangle; + + TetrisAchievement(Rectangle textRectangle) { + this.textRectangle = textRectangle; + + } + + public void render(final Graphics2D graphics) { + + String value = ""; + for (String s: tetris.getAchievements()) { + value += s + "\n"; + } + + Text AchievementText = new Text(value, fontCache.getDefaultFont()); + + SwingUtils.renderCenteredText(graphics, textRectangle, AchievementText); + } + } + + public TetrisAchievementsView(final FontCache fontCache, + final ImageCache imageCache, final Tetris tetris) { + super(fontCache, imageCache, tetris); + + AchievementsRectangle = new Rectangle(0, BLOCK_SIZE, BLOCK_SIZE*24, BLOCK_SIZE*2); + + AchievementsTitleText = new Text(ACHOEVEMENTS, fontCache.getDefaultFont()); + + initializeComponent(AchievementsRectangle.width + 1, AchievementsRectangle.height + BLOCK_SIZE + 1); + } + + private TetrisAchievement createTetrisAchievement() { + + final Rectangle textRectangle = new Rectangle( + BLOCK_SIZE*12, BLOCK_SIZE + 10, 10, 10); + + return new TetrisAchievement(textRectangle); + } + + @Override + protected void doPaint(final Graphics2D graphics) { + SwingUtils.drawRectangleWithTitle(graphics, AchievementsRectangle, AchievementsTitleText); + TetrisAchievement ta = createTetrisAchievement(); + ta.render(graphics); + } +} diff --git a/src/main/java/spypunk/tetris/ui/view/TetrisGridView.java b/src/main/java/spypunk/tetris/ui/view/TetrisGridView.java index 3010add..4788500 100644 --- a/src/main/java/spypunk/tetris/ui/view/TetrisGridView.java +++ b/src/main/java/spypunk/tetris/ui/view/TetrisGridView.java @@ -36,6 +36,8 @@ public class TetrisGridView extends AbstractTetrisView { private static final String PRESS_SPACE = "PRESS SPACE"; + private static String ACHIEVEMENTS = "ACHIEVEMENTS"; + private final Rectangle gridRectangle; private final Text tetrisStoppedText; @@ -55,6 +57,7 @@ public TetrisGridView(final FontCache fontCache, tetrisStoppedText = new Text(PRESS_SPACE, fontCache.getBiggerFont()); tetrisGameOverText = new Text(GAME_OVER, fontCache.getBiggerFont()); tetrisPausedText = new Text(PAUSE, fontCache.getBiggerFont()); + tetrisAchievementsText = new Text(ACHIEVEMENTS, fontCache.getDefaultFont()); initializeComponentWithBorders(gridRectangle.width, gridRectangle.height); } diff --git a/src/main/java/spypunk/tetris/ui/view/TetrisInfoView.java b/src/main/java/spypunk/tetris/ui/view/TetrisInfoView.java index 0e8eff7..6bb2d69 100644 --- a/src/main/java/spypunk/tetris/ui/view/TetrisInfoView.java +++ b/src/main/java/spypunk/tetris/ui/view/TetrisInfoView.java @@ -42,6 +42,8 @@ public class TetrisInfoView extends AbstractTetrisView { private static final String ROWS = "ROWS"; + private static final String ACHIEVEMENTS = "ACHIEVEMENTS"; + private final ValueTetrisInfo rowsTetrisInfo; private final ValueTetrisInfo scoreTetrisInfo; @@ -50,6 +52,8 @@ public class TetrisInfoView extends AbstractTetrisView { private final NextShapeTetrisInfo nextShapeTetrisInfo; + private final ValueTetrisInfo achievementsTetrisInfo; + private abstract class TetrisInfo { protected final Rectangle rectangle; @@ -121,13 +125,15 @@ public TetrisInfoView(final FontCache fontCache, final ImageCache imageCache, final Tetris tetris) { super(fontCache, imageCache, tetris); - final Rectangle levelRectangle = new Rectangle(0, BLOCK_SIZE * 3, BLOCK_SIZE * 6, BLOCK_SIZE); - final Rectangle scoreRectangle = new Rectangle(0, BLOCK_SIZE * 6, BLOCK_SIZE * 6, BLOCK_SIZE); - final Rectangle rowsRectangle = new Rectangle(0, BLOCK_SIZE * 9, BLOCK_SIZE * 6, BLOCK_SIZE); + final Rectangle levelRectangle = new Rectangle(0, BLOCK_SIZE * 2, BLOCK_SIZE * 6, BLOCK_SIZE); + final Rectangle scoreRectangle = new Rectangle(0, BLOCK_SIZE * 4, BLOCK_SIZE * 6, BLOCK_SIZE); + final Rectangle rowsRectangle = new Rectangle(0, BLOCK_SIZE * 6, BLOCK_SIZE * 6, BLOCK_SIZE); + final Rectangle achievementsRectangle = new Rectangle(0, BLOCK_SIZE * 9, BLOCK_SIZE * 6, BLOCK_SIZE); rowsTetrisInfo = new ValueTetrisInfo(rowsRectangle, ROWS); scoreTetrisInfo = new ValueTetrisInfo(scoreRectangle, SCORE); levelTetrisInfo = new ValueTetrisInfo(levelRectangle, LEVEL); + achievementsTetrisInfo = new ValueTetrisInfo(achievementsRectangle, ACHIEVEMENTS); nextShapeTetrisInfo = new NextShapeTetrisInfo(); initializeComponent(VIEW_WIDTH, VIEW_HEIGHT); @@ -138,6 +144,7 @@ protected void doPaint(final Graphics2D graphics) { levelTetrisInfo.render(graphics, tetris.getLevel()); scoreTetrisInfo.render(graphics, tetris.getScore()); rowsTetrisInfo.render(graphics, tetris.getCompletedRows()); + achievementsTetrisInfo.render(graphics, tetris.getAchievementCount()); nextShapeTetrisInfo.render(graphics); } } diff --git a/src/main/java/spypunk/tetris/ui/view/TetrisMainViewImpl.java b/src/main/java/spypunk/tetris/ui/view/TetrisMainViewImpl.java index 245c98e..3c46171 100644 --- a/src/main/java/spypunk/tetris/ui/view/TetrisMainViewImpl.java +++ b/src/main/java/spypunk/tetris/ui/view/TetrisMainViewImpl.java @@ -119,6 +119,7 @@ public TetrisMainViewImpl(final TetrisController tetrisController, final TetrisStatisticsView tetrisStatisticsView = new TetrisStatisticsView(fontCache, imageCache, tetris); final TetrisInfoView tetrisInfoView = new TetrisInfoView(fontCache, imageCache, tetris); final TetrisGridView tetrisGridView = new TetrisGridView(fontCache, imageCache, tetris); + final TetrisAchievementsView tetrisAchievementsView = new TetrisAchievementsView(fontCache, imageCache, tetris); muteImageIcon = new ImageIcon(imageCache.getIcon(Icon.MUTE)); unmuteImageIcon = new ImageIcon(imageCache.getIcon(Icon.UNMUTE)); @@ -149,6 +150,7 @@ public TetrisMainViewImpl(final TetrisController tetrisController, centerPanel.add(tetrisGridView.getComponent(), BorderLayout.CENTER); centerPanel.add(tetrisStatisticsView.getComponent(), BorderLayout.WEST); centerPanel.add(tetrisInfoView.getComponent(), BorderLayout.EAST); + centerPanel.add(tetrisAchievementsView.getComponent(), BorderLayout.SOUTH); frame = new JFrame(tetris.getName() + " " + tetris.getVersion()); From 7e73ad214a0c235b8cee70fce798b9f877085e84 Mon Sep 17 00:00:00 2001 From: Caglayan Demirci Date: Tue, 15 Dec 2020 15:09:00 +0300 Subject: [PATCH 4/9] fix lost touches mistake --- src/main/java/spypunk/tetris/ui/view/TetrisGridView.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/spypunk/tetris/ui/view/TetrisGridView.java b/src/main/java/spypunk/tetris/ui/view/TetrisGridView.java index 4788500..9ec965a 100644 --- a/src/main/java/spypunk/tetris/ui/view/TetrisGridView.java +++ b/src/main/java/spypunk/tetris/ui/view/TetrisGridView.java @@ -46,6 +46,8 @@ public class TetrisGridView extends AbstractTetrisView { private final Text tetrisPausedText; + private final Text tetrisAchievementsText; + public TetrisGridView(final FontCache fontCache, final ImageCache imageCache, final Tetris tetris) { From 15e1e32932b1e8dbbd5f70519abe5e712992b7ff Mon Sep 17 00:00:00 2001 From: Caglayan Demirci Date: Tue, 15 Dec 2020 21:32:14 +0300 Subject: [PATCH 5/9] delete unnecessary whitespaces --- .../tetris/ui/view/TetrisAchievementsView.java | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/main/java/spypunk/tetris/ui/view/TetrisAchievementsView.java b/src/main/java/spypunk/tetris/ui/view/TetrisAchievementsView.java index 457b5af..243314e 100644 --- a/src/main/java/spypunk/tetris/ui/view/TetrisAchievementsView.java +++ b/src/main/java/spypunk/tetris/ui/view/TetrisAchievementsView.java @@ -27,13 +27,10 @@ public class TetrisAchievementsView extends AbstractTetrisView { private static final String ACHOEVEMENTS = "ACHIEVEMENTS"; - private final Rectangle AchievementsRectangle; - private final Text AchievementsTitleText; private class TetrisAchievement { - private final Rectangle textRectangle; TetrisAchievement(Rectangle textRectangle) { @@ -42,34 +39,26 @@ private class TetrisAchievement { } public void render(final Graphics2D graphics) { - String value = ""; for (String s: tetris.getAchievements()) { value += s + "\n"; } - Text AchievementText = new Text(value, fontCache.getDefaultFont()); - SwingUtils.renderCenteredText(graphics, textRectangle, AchievementText); } } public TetrisAchievementsView(final FontCache fontCache, - final ImageCache imageCache, final Tetris tetris) { + final ImageCache imageCache, + final Tetris tetris) { super(fontCache, imageCache, tetris); - AchievementsRectangle = new Rectangle(0, BLOCK_SIZE, BLOCK_SIZE*24, BLOCK_SIZE*2); - AchievementsTitleText = new Text(ACHOEVEMENTS, fontCache.getDefaultFont()); - initializeComponent(AchievementsRectangle.width + 1, AchievementsRectangle.height + BLOCK_SIZE + 1); } private TetrisAchievement createTetrisAchievement() { - - final Rectangle textRectangle = new Rectangle( - BLOCK_SIZE*12, BLOCK_SIZE + 10, 10, 10); - + final Rectangle textRectangle = new Rectangle(BLOCK_SIZE*12, BLOCK_SIZE + 10, 10, 10); return new TetrisAchievement(textRectangle); } From b1e97ffbb65d505cf21912eea27bfc0235989ddb Mon Sep 17 00:00:00 2001 From: Caglayan Demirci Date: Tue, 15 Dec 2020 21:33:00 +0300 Subject: [PATCH 6/9] make achievement tresholds parametric --- .../java/spypunk/tetris/model/Tetris.java | 48 ++++++++++++--- .../spypunk/tetris/model/TetrisInstance.java | 61 +++++++++++++++---- .../tetris/service/TetrisServiceImpl.java | 44 +++++++------ 3 files changed, 116 insertions(+), 37 deletions(-) diff --git a/src/main/java/spypunk/tetris/model/Tetris.java b/src/main/java/spypunk/tetris/model/Tetris.java index eba69bd..9e5fbf8 100644 --- a/src/main/java/spypunk/tetris/model/Tetris.java +++ b/src/main/java/spypunk/tetris/model/Tetris.java @@ -154,20 +154,52 @@ public void addAchievement(String achievement) { tetrisInstance.addAchievement(achievement); } - public boolean isRowAbove25() { - return tetrisInstance.IsRowAbove25(); + public boolean isRowAboveN() { + return tetrisInstance.IsRowAboveN(); } - public void setRowAbove25() { - tetrisInstance.setRowAbove25(); + public void setRowAboveN() { + tetrisInstance.setRowAboveN(); } - public boolean isScoreAbove1000() { - return tetrisInstance.IsScoreAbove1000(); + public boolean isScoreAboveN() { + return tetrisInstance.IsScoreAboveN(); } - public void setScoreAbove1000() { - tetrisInstance.setScoreAbove1000(); + public void setScoreAboveN() { + tetrisInstance.setScoreAboveN(); + } + + public int getNForRow() { + return tetrisInstance.getNForRow(); + } + + public void setNForRow(int n) { + tetrisInstance.setNForRow(n); + } + + public int getNForScore() { + return tetrisInstance.getNForScore(); + } + + public void setNForScore(int n) { + tetrisInstance.setNForScore(n); + } + + public boolean getAchievementUnlocked_ROW() { + return tetrisInstance.isAchievementUnlocked_ROW(); + } + + public void setAchievementUnlocked_ROW() { + tetrisInstance.setAchievementUnlocked_ROW(); + } + + public boolean getAchievementUnlocked_SCORE() { + return tetrisInstance.isAchievementUnlocked_SCORE(); + } + + public void setAchievementUnlocked_SCORE() { + tetrisInstance.setAchievementUnlocked_SCORE(); } public int getSpeed() { diff --git a/src/main/java/spypunk/tetris/model/TetrisInstance.java b/src/main/java/spypunk/tetris/model/TetrisInstance.java index 172fc7b..5dc56c9 100644 --- a/src/main/java/spypunk/tetris/model/TetrisInstance.java +++ b/src/main/java/spypunk/tetris/model/TetrisInstance.java @@ -44,10 +44,15 @@ public class TetrisInstance { private int achievementCount; private ArrayList achievements = new ArrayList<>(); + private boolean rowAboveN = false; + private int nForRow; + private boolean scoreAboveN = false; + private int nForScore; - private boolean rowAbove25 = false; - - private boolean scoreAbove1000 = false; + // I need extra booleans in order for the game loop does + // not update the achievements when they are unlocked once. + private boolean achievementUnlocked_ROW = false; + private boolean achievementUnlocked_SCORE = false; private int speed; @@ -116,21 +121,55 @@ public void setAchievementCount(int achievementCount) { this.achievementCount = achievementCount; } - public boolean IsRowAbove25() { - return rowAbove25; + public boolean IsRowAboveN() { + return getNForRow() <= getCompletedRows(); + } + + public void setRowAboveN() { + this.rowAboveN = !this.rowAboveN; + } + + public boolean IsScoreAboveN() { + return getNForScore() <= getScore(); } - public void setRowAbove25() { - this.rowAbove25 = !this.rowAbove25; + + public void setScoreAboveN() { + this.scoreAboveN = !this.scoreAboveN; + } + + public int getNForRow() { + return nForRow; + } + + public void setNForRow(int n) { + this.nForRow = n; } - public boolean IsScoreAbove1000() { - return scoreAbove1000; + public int getNForScore() { + return nForScore; } - public void setScoreAbove1000() { - this.scoreAbove1000 = !this.scoreAbove1000; + public void setNForScore(int n) { + this.nForScore = n; } + public boolean isAchievementUnlocked_ROW() { + return achievementUnlocked_ROW; + } + + public void setAchievementUnlocked_ROW() { + achievementUnlocked_ROW = !achievementUnlocked_ROW; + } + + public boolean isAchievementUnlocked_SCORE() { + return achievementUnlocked_SCORE; + } + + public void setAchievementUnlocked_SCORE() { + achievementUnlocked_SCORE = !achievementUnlocked_SCORE; + } + + public ArrayList getAchievements() { return achievements; } diff --git a/src/main/java/spypunk/tetris/service/TetrisServiceImpl.java b/src/main/java/spypunk/tetris/service/TetrisServiceImpl.java index fcdcd30..c241e93 100644 --- a/src/main/java/spypunk/tetris/service/TetrisServiceImpl.java +++ b/src/main/java/spypunk/tetris/service/TetrisServiceImpl.java @@ -193,9 +193,35 @@ private void updateStatistics() { final Integer count = statistics.get(shapeType); statistics.put(shapeType, count + 1); + + achievement_score10(); + achievement_row1(); updateAchievements(); } + private void updateAchievements() { + + if (!tetris.getAchievementUnlocked_SCORE() && tetris.isScoreAboveN()) { + updateAchievementCount(); + tetris.addAchievement("YOU REACHED SCORE " + tetris.getNForScore()); + tetris.setAchievementUnlocked_SCORE(); + } + if (!tetris.getAchievementUnlocked_ROW() && tetris.isRowAboveN()) { + updateAchievementCount(); + tetris.addAchievement("YOU HAVE DESTROYED " + tetris.getNForRow() + " ROWS!"); + tetris.setAchievementUnlocked_ROW(); + } + } + + // instance achievements + private void achievement_score10() { + tetris.setNForScore(10); + } + + private void achievement_row1() { + tetris.setNForRow(1); + } + private boolean isGameOver() { return tetris.getBlocks().values().stream() .anyMatch(block -> block.getLocation().y == 0); @@ -260,24 +286,6 @@ private void clearCompleteRow(final int row) { blocksToMoveDown.forEach(this::moveBlockDown); } - private void updateAchievements() { - int currentScore = tetris.getScore(), - currentRow = tetris.getCompletedRows(); - boolean scoreIsAbove1000 = false, - rowsIsAbove50 = false; - - if (!tetris.isScoreAbove1000() && currentScore >= 1000) { - updateAchievementCount(); - tetris.addAchievement("YOU REACHED SCORE 1000!"); - tetris.setScoreAbove1000(); - } - if (!tetris.isRowAbove25() && currentRow >= 25) { - updateAchievementCount(); - tetris.addAchievement("YOU HAVE DESTROYED 25 ROWS!"); - tetris.setRowAbove25(); - } - } - private void updateAchievementCount() { tetris.setAchievementCount(tetris.getAchievementCount() + 1); } From 3fc47f568e496258a6d2a7076434a2681a9eb4f8 Mon Sep 17 00:00:00 2001 From: Caglayan Demirci Date: Tue, 15 Dec 2020 22:41:54 +0300 Subject: [PATCH 7/9] add a test class --- .../java/spypunk/tetris/AchievementTest.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/main/java/spypunk/tetris/AchievementTest.java diff --git a/src/main/java/spypunk/tetris/AchievementTest.java b/src/main/java/spypunk/tetris/AchievementTest.java new file mode 100644 index 0000000..60800f0 --- /dev/null +++ b/src/main/java/spypunk/tetris/AchievementTest.java @@ -0,0 +1,30 @@ +package spypunk.tetris; + +import org.junit.jupiter.api.Test; +import spypunk.tetris.model.Tetris; +import spypunk.tetris.model.TetrisInstance; + +import static org.junit.Assert.assertFalse; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.*; + +public class AchievementTest { + + @Test + void testAchievementNotUnlocked() { + + Tetris t = mock(Tetris.class); + TetrisInstance ti = mock(TetrisInstance.class); + + assertEquals(ti.getAchievementCount(), 0); + assertFalse(ti.isAchievementUnlocked_ROW()); + assertFalse(ti.isAchievementUnlocked_SCORE()); + + } + + @Test + void testAchievementSCORE() { + + } + +} \ No newline at end of file From ee792a206262029866343d315c14a3196b6dd10f Mon Sep 17 00:00:00 2001 From: Caglayan Demirci Date: Wed, 16 Dec 2020 19:18:25 +0300 Subject: [PATCH 8/9] fix a build mistake --- pom.xml | 17 +++++++++++++++++ .../spypunk/tetris/model/TetrisInstance.java | 1 - 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9e992f8..61f19c4 100644 --- a/pom.xml +++ b/pom.xml @@ -154,5 +154,22 @@ commons-lang3 3.6 + + junit + junit + 4.12 + compile + + + org.junit.jupiter + junit-jupiter + RELEASE + compile + + + org.mockito + mockito-core + 2.27.0 + diff --git a/src/main/java/spypunk/tetris/model/TetrisInstance.java b/src/main/java/spypunk/tetris/model/TetrisInstance.java index 5dc56c9..b9094b6 100644 --- a/src/main/java/spypunk/tetris/model/TetrisInstance.java +++ b/src/main/java/spypunk/tetris/model/TetrisInstance.java @@ -169,7 +169,6 @@ public void setAchievementUnlocked_SCORE() { achievementUnlocked_SCORE = !achievementUnlocked_SCORE; } - public ArrayList getAchievements() { return achievements; } From 14a3bb53ee3964791d753858421e10dae59fe4e5 Mon Sep 17 00:00:00 2001 From: Caglayan Demirci Date: Thu, 24 Dec 2020 22:42:37 +0300 Subject: [PATCH 9/9] implement TetrisAchievement and Checker classes --- .../java/spypunk/tetris/model/Tetris.java | 6 +- .../tetris/model/TetrisAchievement.java | 66 +++++++++++++++++++ .../model/TetrisAchievementChecker.java | 35 ++++++++++ .../spypunk/tetris/model/TetrisInstance.java | 8 +-- .../tetris/service/TetrisServiceImpl.java | 23 +++++-- .../ui/view/TetrisAchievementsView.java | 7 +- 6 files changed, 129 insertions(+), 16 deletions(-) create mode 100644 src/main/java/spypunk/tetris/model/TetrisAchievement.java create mode 100644 src/main/java/spypunk/tetris/model/TetrisAchievementChecker.java diff --git a/src/main/java/spypunk/tetris/model/Tetris.java b/src/main/java/spypunk/tetris/model/Tetris.java index 9e5fbf8..f9e6e2d 100644 --- a/src/main/java/spypunk/tetris/model/Tetris.java +++ b/src/main/java/spypunk/tetris/model/Tetris.java @@ -146,12 +146,12 @@ public void setAchievementCount(final int achievementCount) { tetrisInstance.setAchievementCount(achievementCount); } - public ArrayList getAchievements() { + public ArrayList getAchievements() { return tetrisInstance.getAchievements(); } - public void addAchievement(String achievement) { - tetrisInstance.addAchievement(achievement); + public void addAchievement(TetrisAchievement ta) { + tetrisInstance.addAchievement(ta); } public boolean isRowAboveN() { diff --git a/src/main/java/spypunk/tetris/model/TetrisAchievement.java b/src/main/java/spypunk/tetris/model/TetrisAchievement.java new file mode 100644 index 0000000..b3f72f6 --- /dev/null +++ b/src/main/java/spypunk/tetris/model/TetrisAchievement.java @@ -0,0 +1,66 @@ +package spypunk.tetris.model; + +import java.util.Map; + +public class TetrisAchievement { + private Tetris tetris; + private String name; + private String message; + String achievementType; + private ShapeType shapeType; + private int threshold; + private boolean achievementUnlocked; + + public ShapeType getShapeType() { + return shapeType; + } + + public String getName() { + return name; + } + + public Tetris getTetris() { + return tetris; + } + + public String getAchievementType() { + return achievementType; + } + + public String getMessage() { + return message; + } + + public int getThreshold() { + return threshold; + } + + public boolean isAchievementUnlocked() { + return achievementUnlocked; + } + + public void setAchievementUnlocked(boolean exp) { + this.achievementUnlocked = exp; + } + + public TetrisAchievement(String name, String message, String achievementType, int threshold) { + shapeType = null; + achievementUnlocked = false; + this.name = name; + this.message = message; + this.threshold = threshold; + } + + public TetrisAchievement(String name, String message, ShapeType shapeType, int threshold) { + /* + In this type of achievement, programmer is able to count + how many times of using any shape type. Any type and any threshold value + can unlock such an achievement. + */ + achievementUnlocked = false; + this.name = name; + this.message = message; + this.threshold = threshold; + } + +} diff --git a/src/main/java/spypunk/tetris/model/TetrisAchievementChecker.java b/src/main/java/spypunk/tetris/model/TetrisAchievementChecker.java new file mode 100644 index 0000000..9e03d09 --- /dev/null +++ b/src/main/java/spypunk/tetris/model/TetrisAchievementChecker.java @@ -0,0 +1,35 @@ +package spypunk.tetris.model; + +import spypunk.tetris.ui.view.TetrisAchievementsView; + +import java.util.Map; + +public class TetrisAchievementChecker { + private TetrisAchievement ta; + + public TetrisAchievementChecker(TetrisAchievement ta) { + this.ta = ta; + } + + public void checkAchievement() { + if (ta.getShapeType() == null) { // that means this achievement is related to score or row + if (ta.getAchievementType().equals("SCORE")) { + ta.getTetris().setNForScore(ta.getThreshold()); + // controls can be done in my previous methods. + } + if (ta.getAchievementType().equals("ROW")) { + ta.getTetris().setNForRow(ta.getThreshold()); + } + } + else { + for (Map.Entry entry: ta.getTetris().getStatistics().entrySet()) { + if (entry.getKey().equals(ta.getShapeType()) && entry.getValue() >= ta.getThreshold()) { + if (!ta.isAchievementUnlocked()) { + ta.setAchievementUnlocked(true); + ta.getTetris().addAchievement(ta); + } + } + } + } + } +} diff --git a/src/main/java/spypunk/tetris/model/TetrisInstance.java b/src/main/java/spypunk/tetris/model/TetrisInstance.java index b9094b6..43065f2 100644 --- a/src/main/java/spypunk/tetris/model/TetrisInstance.java +++ b/src/main/java/spypunk/tetris/model/TetrisInstance.java @@ -43,7 +43,7 @@ public class TetrisInstance { private int achievementCount; - private ArrayList achievements = new ArrayList<>(); + private ArrayList achievements = new ArrayList<>(); private boolean rowAboveN = false; private int nForRow; private boolean scoreAboveN = false; @@ -169,12 +169,12 @@ public void setAchievementUnlocked_SCORE() { achievementUnlocked_SCORE = !achievementUnlocked_SCORE; } - public ArrayList getAchievements() { + public ArrayList getAchievements() { return achievements; } - public void addAchievement(String achievement) { - this.achievements.add(achievement); + public void addAchievement(TetrisAchievement ta) { + this.achievements.add(ta); } public void setScore(final int score) { diff --git a/src/main/java/spypunk/tetris/service/TetrisServiceImpl.java b/src/main/java/spypunk/tetris/service/TetrisServiceImpl.java index c241e93..638520f 100644 --- a/src/main/java/spypunk/tetris/service/TetrisServiceImpl.java +++ b/src/main/java/spypunk/tetris/service/TetrisServiceImpl.java @@ -27,14 +27,10 @@ import spypunk.tetris.factory.ShapeFactory; import spypunk.tetris.guice.TetrisModule.TetrisProvider; -import spypunk.tetris.model.Movement; -import spypunk.tetris.model.Shape; +import spypunk.tetris.model.*; import spypunk.tetris.model.Shape.Block; -import spypunk.tetris.model.ShapeType; -import spypunk.tetris.model.Tetris; import spypunk.tetris.model.Tetris.State; -import spypunk.tetris.model.TetrisEvent; -import spypunk.tetris.model.TetrisInstance; +import spypunk.tetris.ui.view.TetrisAchievementsView; @Singleton public class TetrisServiceImpl implements TetrisService { @@ -196,11 +192,11 @@ private void updateStatistics() { achievement_score10(); achievement_row1(); - updateAchievements(); } private void updateAchievements() { + /* if (!tetris.getAchievementUnlocked_SCORE() && tetris.isScoreAboveN()) { updateAchievementCount(); tetris.addAchievement("YOU REACHED SCORE " + tetris.getNForScore()); @@ -211,6 +207,7 @@ private void updateAchievements() { tetris.addAchievement("YOU HAVE DESTROYED " + tetris.getNForRow() + " ROWS!"); tetris.setAchievementUnlocked_ROW(); } + */ } // instance achievements @@ -222,6 +219,18 @@ private void achievement_row1() { tetris.setNForRow(1); } + // an instance achievement after implementing TetrisAchievement class + private void achievementIHaveUsed100LShapes() { + TetrisAchievement ta = new TetrisAchievement( + "L destroyer", + "You have used 100 L-shaped blocks!", + ShapeType.L, + 100 + ); + + TetrisAchievementChecker tac = new TetrisAchievementChecker(ta); + } + private boolean isGameOver() { return tetris.getBlocks().values().stream() .anyMatch(block -> block.getLocation().y == 0); diff --git a/src/main/java/spypunk/tetris/ui/view/TetrisAchievementsView.java b/src/main/java/spypunk/tetris/ui/view/TetrisAchievementsView.java index 243314e..d4877fd 100644 --- a/src/main/java/spypunk/tetris/ui/view/TetrisAchievementsView.java +++ b/src/main/java/spypunk/tetris/ui/view/TetrisAchievementsView.java @@ -19,6 +19,8 @@ import spypunk.tetris.model.ShapeType; import spypunk.tetris.model.Tetris; +import spypunk.tetris.model.TetrisAchievement; +import spypunk.tetris.model.TetrisAchievementChecker; import spypunk.tetris.ui.cache.ImageCache; import spypunk.tetris.ui.font.cache.FontCache; import spypunk.tetris.ui.util.SwingUtils; @@ -26,6 +28,7 @@ public class TetrisAchievementsView extends AbstractTetrisView { + private static final String ACHOEVEMENTS = "ACHIEVEMENTS"; private final Rectangle AchievementsRectangle; private final Text AchievementsTitleText; @@ -40,8 +43,8 @@ private class TetrisAchievement { public void render(final Graphics2D graphics) { String value = ""; - for (String s: tetris.getAchievements()) { - value += s + "\n"; + for (spypunk.tetris.model.TetrisAchievement ta: tetris.getAchievements()) { + value += ta.getMessage() + "\n"; } Text AchievementText = new Text(value, fontCache.getDefaultFont()); SwingUtils.renderCenteredText(graphics, textRectangle, AchievementText);