commit da8907013cb14b75b43dc8f036dc913da5ef12ae Author: aidan Date: Sun Feb 23 23:18:27 2025 -0500 Clone diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..02c5148 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# 2048-Java-Processing + +Requires Processing Library diff --git a/button.java b/button.java new file mode 100644 index 0000000..63ed8b1 --- /dev/null +++ b/button.java @@ -0,0 +1,38 @@ + +public class button { + int x1, y1, x2, y2, xLength, yLength, r = 16, fontSize; + boolean enabled = false; + String action, text; + boolean activated = false; + + public button() { + + } + + public button(String a, String text) { + action = a; + this.text = text; + } + + public void setValues(int x1, int y1, int xLength, int yLength, int fontSize) { + this.x1 = x1; + this.y1 = y1; + this.xLength = xLength; + this.yLength = yLength; + x2 = (int) (x1 + xLength); + y2 = (int) (y1 + yLength); + + this.fontSize = fontSize; + + activated = true; // Assumes values are being updated because button is active. + } + + public void activate() { + activated = true; + } + + public void deactivate() { + activated = false; + } + +} diff --git a/runner.java b/runner.java new file mode 100644 index 0000000..66298eb --- /dev/null +++ b/runner.java @@ -0,0 +1,530 @@ +import java.util.ArrayList; +import java.util.Random; + +import processing.core.PApplet; +import processing.core.PFont; + +/* + * To-Do + * Finish Options Menu + * Create animations - Create a before and after grid to compare the movements? Need to animate the new piece too + * Game mode: Timer + * + * */ + +public class runner extends PApplet{ + Random r = new Random(); + + int[] values = {2, 2, 2, 2, 2, 2, 2, 2, 2, 4}; + final double uiy = 0.25; + int yq; + int gridSize = 4; + boolean hasWon = false; + tile grid[][], tempGrid[][]; + variables v; + + PFont BOLD, REGULAR; + + public void settings() { + size(600,800); + } + + public void setup() { + surface.setResizable(true); // Is it possible for an "onResize" function? + surface.setTitle("2048"); + BOLD = createFont("Arial Bold", 16, true); + REGULAR = createFont("Arial", 16, true); + v = new variables(); + resetVars(); + frameRate(30); + } + + public void draw() { + background(255); + drawGame(); + drawUI(); + } + + public void drawUI() { + int r = 16; + yq = (int) (uiy * height); + + fill(250,248,238); + rect(0, 0, width, yq, r, r, r, r); + + textAlign(CENTER); + + textFont(BOLD); + fill(119,110,101); + drawText("2048", (int) (width * 0.1875), (int) (height * uiy * 0.5), (int) (width / 9.375)); + drawText("Score: " + v.gameScore, (int) (width * 0.1875), (int) (height * uiy * 0.7), (int) (width / 15)); + + fill(255); + v.buttons.get(1).setValues((int) (width * 0.5), (int)(height * uiy * 0.25), (int) (width / 4.8), (int) (height / 10.667), (int) (width / 30)); // This would be better with a window resized listener if the game is ported to a better engine + drawButton(v.buttons.get(1)); // Make this a for loop later. + fill(255); + v.buttons.get(2).setValues((int) ((width * 0.525) + (width / 4.8)), (int)(height * uiy * 0.25), (int) (width / 4.8), (int) (height / 10.667), (int) (width / 30)); + drawButton(v.buttons.get(2)); // Make this a for loop later. + + if (v.gameOver) { + drawGameOverUI(); + } + else if (v.showOptionsUI) { + drawOptionsUI(); + } + else if (v.showGameWonUI) { + drawGameWonUI(); + } + } + + public void drawGameOverUI() { + noStroke(); + fill(0,0,0,100); + rect(0, yq, width, height); + + drawText("Game Over!", width / 2, height / 2, (int) (width / 12.5), 255); + fill(237,197, 63); + v.buttons.get(0).setValues((int) (width * 0.25), (int) (height * 0.55), (int) (width * 0.5), (int) (height * 0.125), (int) (width / 18.75)); + drawButton(v.buttons.get(0)); + } + + public void drawGameWonUI() { + noStroke(); + fill(0,0,0,100); + rect(0, yq, width, height); + + drawText("2048!", width / 2, height / 2, (int) (width / 12.5), 255); + + fill(237,197, 63); + v.buttons.get(0).setValues((int) (width * 0.25), (int) (height * 0.55), (int) (width * 0.5), (int) (height * 0.125), (int) (width / 18.75)); + drawButton(v.buttons.get(0)); + + fill(237,197, 63); + v.buttons.get(3).setValues((int) (width * 0.25), (int) (height * 0.7), (int) (width * 0.5), (int) (height * 0.125), (int) (width / 18.75)); + drawButton(v.buttons.get(3)); + } + + public void drawOptionsUI() { + noStroke(); + + // Hidden buttons for the UI + + + fill(0,0,0,100); + rect(0, yq, width, height); + + int xPadding = (int) (width * 0.1); + int yPadding = (int) (height * 0.05); + int r = 16; + + int xOptionsArea = (int) (width * 0.05) + xPadding; + int yOptionsArea = (int) (height * 0.1) + yq + yPadding; + + fill(255); + rect(xPadding, yq + yPadding, width - (int) (xPadding * 2), (int) (height - yq - yPadding * 2), r, r, r, r); + + drawText(v.language[2], xPadding + (int) (width * 0.15), yPadding + yq + (int) (height * 0.05), (int) (width / 18.75), 0); + stroke(5); + line(xPadding + (int) (width * 0.05), yPadding + yq + (int) (height * 0.1), width - (xPadding + (int) (width * 0.05)), yPadding + yq + (int) (height * 0.1)); + + updateOptionsContext(); + // For loop of each option + for (int i = 0; i < v.optionsLanguage.length; i++) { + textAlign(LEFT, TOP); + drawText(v.optionsLanguage[i], xOptionsArea, yOptionsArea + (int) (i * (height * 0.05)), (int) (width * 0.04), 0); + textAlign(RIGHT, TOP); + drawText(v.optionsContext[i], width - xOptionsArea, yOptionsArea + (int) (i * (height * 0.05)), (int) (width * 0.04), 0); + } + + fill(0); + for (int i = 0; i < v.optionMenuButtons.size(); i++) { + v.optionMenuButtons.get(i).setValues(xOptionsArea, yOptionsArea + (int) (i * (height * 0.05)), (int) (width - xOptionsArea * 2), (int) (height * 0.04), 1); + } + + } + + public void updateOptionsContext() { + v.optionsContext[0] = gridSize + " x " + gridSize; + } + + /* + * Parameters: Area start X, Area Start Y, Area end X, Area end Y + */ + public boolean isMouseInArea(int x1, int y1, int x2, int y2) { + return (mouseX >= x1 && mouseY >= y1 && mouseX <= x2 && mouseY <= y2); + } + + public void mouseClicked() { + for(button x : v.buttons) { + if(isMouseInArea(x.x1, x.y1, x.x2, x.y2)) { + buttonHandler(x); + } + } + for (button x : v.optionMenuButtons) { + if(isMouseInArea(x.x1, x.y1, x.x2, x.y2)) { + buttonHandler(x); + } + } + } + + public void buttonHandler(button x) { + if (x.activated) { + if(x.action == "Retry") { + resetVars(); + } + else if (x.action == "New Game") { + resetVars(); + } + else if (x.action == "Options") { + v.showOptionsUI = !v.showOptionsUI; + } + else if (x.action == "Continue") { + v.showGameWonUI = false; + } + else if (x.action == "Grid Size") { + flipGridSize(); + } + } + } + + public void flipGridSize() { + if(gridSize == 4) { + setGridSize(5); + } + else { + setGridSize(4); + } + resetVars(); + + } + + public void drawButton(button x) { + rect(x.x1, x.y1, x.xLength, x.yLength, x.r, x.r, x.r, x.r); + textAlign(CENTER, CENTER); + drawText(x.text, (int) ((x.x2 + x.x1)/2), (int) ((x.y1 + x.y2)/2.025), (int) x.fontSize, 0); + } + + public void drawGame() { + v.gameXSize = width / gridSize; + v.gameYSize = (height - yq) / gridSize; + double spacing = 0.1; + int xSpacing = (int) (v.gameXSize * spacing); + int ySpacing = (int) (v.gameYSize * spacing); + + noStroke(); + fill(187, 173, 160); + rect(0, 0, width, height); + strokeWeight(v.gameStrokeSize); + stroke(1); + + for(int i = 0; i < grid.length; i++) { + for(int k = 0; k < grid[0].length; k++) { + tile temp = grid[i][k]; + int cl = tileColor(temp); + fill(v.colors[cl].r, v.colors[cl].g, v.colors[cl].b); // Figure out how Processing generates color code to simplify this. + rect((int) (v.gameXSize * i + xSpacing * 0.5), (int) ((v.gameYSize * k) + yq + ySpacing * 0.5), v.gameXSize - xSpacing, v.gameYSize - ySpacing, 8, 8, 8, 8); + if(!temp.isEmpty()) { + fill(0); + textAlign(CENTER); + drawText(temp.value + "", (int) (v.gameXSize * i + v.gameXSize * 0.5 + xSpacing * 0.5), (int) ((v.gameYSize * k + v.gameYSize * 0.5) + yq + ySpacing * 0.5), 32); + } + } + } + } + + public void checkWinConditions() { + for (int i = 0; i < grid.length; i++) { + for (int k = 0; k < grid[0].length; k++) { + if (grid[i][k].value == 2048 && !hasWon && true) {// Replace true with the game mode + hasWon = true; + v.showGameWonUI = true; + } + } + } + } + + public int tileColor(tile temp) { + int cl = temp.colorLevel(); + if(cl >= v.colors.length) + cl = v.colors.length - 1; + return cl; + } + + public int isZero(int x) { + if(x == 0) + return 1; + else + return 0; + } + + public void drawText(String stringText, int x, int y, int size) { + textSize(size); + text(stringText, x, y); + } + public void drawText(String stringText, int x, int y, int size, int color) { + fill(color); + textSize(size); + text(stringText, x, y); + } + + // Gamey Stuff \/ + + public void keyPressed() { + if (key == 'r' || key == 'R') { + resetVars(); + } + else if (key == 'f' || key == 'F') { + undoMove(); + } + else if (key == 't') { + v.showGameWonUI = true; + } + else { + if(!v.gameOver) + moveTiles(); + } + } + + public void resetVars() { + v.gameScore = 0; + hasWon = false; // Used for checking if win condition has been met before + setGridSize(gridSize); + fillGrid(); + resetTempGrid(); + createNewTile(); + v.gameOver = false; + v.showGameWonUI = false; + v.buttons = new ArrayList