This commit is contained in:
Jacob Signorovitch
2025-05-28 08:02:46 -04:00
parent 0b30c851e4
commit 83e80a48e2

View File

@@ -4,6 +4,7 @@ import java.awt.Color;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import javalib.impworld.*;
import javalib.worldimages.*;
import tester.Tester;
@@ -11,10 +12,6 @@ import tester.Tester;
class Examples {
void testRun(Tester t) {
Game game = new Game();
game.board.board.put(new Coord(0, 0), new Tile(2));
game.board.board.put(new Coord(3, 1), new Tile(20));
game.board.board.put(new Coord(3, 2), new Tile(200));
game.board.board.put(new Coord(2, 3), new Tile(2000));
game.run();
}
}
@@ -64,23 +61,36 @@ class Game extends World {
this.sz = Util.defaultWidth;
this.width = this.sz * Util.scale;
this.board = new Board(this.sz);
this.board.randGen();
this.board.randGen();
}
public WorldScene makeScene() {
WorldScene scene = new WorldScene(this.width, this.width);
scene.placeImageXY(this.board.draw(), this.width / 2, this.width / 2);
scene.placeImageXY(
new TextImage("Score: " + this.score, 20, Color.RED),
this.width / 2, 20
);
return scene;
}
public void onKeyEvent(String key) {
System.out.println("got key" + key);
if (key.equals("left") || key.equals("h")) this.board.move(Move.LEFT);
int score = 0;
if (key.equals("left") || key.equals("h"))
score = this.board.move(Move.LEFT);
else if (key.equals("down") || key.equals("j"))
this.board.move(Move.DOWN);
else if (key.equals("up") || key.equals("k")) this.board.move(Move.UP);
score = this.board.move(Move.DOWN);
else if (key.equals("up") || key.equals("k"))
score = this.board.move(Move.UP);
else if (key.equals("right") || key.equals("l"))
this.board.move(Move.RIGHT);
score = this.board.move(Move.RIGHT);
else return;
this.score += score;
}
void run() { this.bigBang(this.width, this.width, 0.01); }
@@ -90,10 +100,14 @@ class Game extends World {
class Board {
int sz; // The side length of the board grid square.
Map<Coord, Cell> board;
Random rand;
boolean boardChanged;
Board(int sz) {
this.sz = sz;
this.board = new HashMap<Coord, Cell>();
this.rand = new Random();
this.boardChanged = false;
}
// Draw the board.
@@ -130,9 +144,7 @@ class Board {
}
// Set the cell at the coords.
void set(Coord coord, Cell cell) {
this.board.put(coord, cell);
}
void set(Coord coord, Cell cell) { this.board.put(coord, cell); }
// Try to move the cell at the coords to the coords.
void tryCellMove(Coord coord, Coord dest) {
@@ -142,47 +154,123 @@ class Board {
if (cell.isMoveable() && destCell.isReplaceable()) {
this.set(dest, cell);
this.set(coord, new Space());
boardChanged = true; // It did move.
}
}
// Move cell as much as possible.
void fullCellMove(Coord coord, Move move) {
// Try to combine two tiles if they have the same value
int tryCombine(Coord source, Coord target) {
Cell sourceCell = this.get(source);
Cell targetCell = this.get(target);
// Check if both cells are tiles.
if (sourceCell instanceof Tile && targetCell instanceof Tile) {
Tile sourceTile = (Tile)sourceCell;
Tile targetTile = (Tile)targetCell;
// Check they've the same n and haven't yet been combined.
if (sourceTile.n == targetTile.n && !targetTile.flag) {
Tile newTile = new Tile(sourceTile.n * 2);
int score = sourceTile.n;
newTile.flag = true;
this.set(target, newTile);
this.set(source, new Space());
boardChanged = true;
return score;
}
}
return 0;
}
// Move cell as much as possible. Return score.
int fullCellMove(Coord coord, Move move) {
Cell cell = this.get(coord);
Coord disp = Util.moveDisp(move);
if (!cell.isMoveable()) return;
if (!cell.isMoveable()) return 0;
for () {
this.tryCellMove(coord, coord.add(disp));
}
Coord current = coord;
Coord next = current.add(disp);
// Keep moving until edge or a non-replaceable cell hit.
while (next.x >= 0 && next.x < this.sz && next.y >= 0 &&
next.y < this.sz && this.get(next).isReplaceable()) {
this.tryCellMove(current, next);
current = next;
next = current.add(disp);
}
// Move in the given direction.
void move(Move move) {
// Check if can combine next tile.
if (next.x >= 0 && next.x < this.sz && next.y >= 0 && next.y < this.sz)
return this.tryCombine(current, next);
// Only generate new tile if changed.
if (boardChanged) this.randGen();
return 0;
}
// Move in the given direction. Returns the generated score.
int move(Move move) {
System.out.println("moving");
for (int i = 0; i < this.sz; i ++) {
this.moveLine(i, move);
// Reset flags for all tiles and change tracker.
resetFlags();
int score = 0;
for (int i = 0; i < this.sz; i++) { score += this.moveLine(i, move); }
return score;
}
// Reset flags of all tiles.
void resetFlags() {
for (int x = 0; x < this.sz; x++)
for (int y = 0; y < this.sz; y++) {
Cell cell = this.get(new Coord(x, y));
if (cell instanceof Tile) ((Tile)cell).flag = false;
}
}
// Move a line of tiles.
void moveLine(int i, Move move) {
if (move.equals(Move.LEFT)) {
for (int x = 1; x < this.sz; x++) {
this.fullCellMove(new Coord(x, i), move);
}
int moveLine(int i, Move move) {
int score = 0;
if (move.equals(Move.LEFT))
for (int x = 1; x < this.sz; x++)
score += this.fullCellMove(new Coord(x, i), move);
else if (move.equals(Move.RIGHT))
for (int x = this.sz - 2; x >= 0; x--)
score += this.fullCellMove(new Coord(x, i), move);
else if (move.equals(Move.DOWN))
for (int y = this.sz - 2; y >= 0; y--)
score += this.fullCellMove(new Coord(i, y), move);
else if (move.equals(Move.UP))
for (int y = 1; y < this.sz; y++)
score += this.fullCellMove(new Coord(i, y), move);
return score;
}
else if (move.equals(Move.RIGHT)) {
for (int x = this.sz - 2; x >= 0; x--) {
this.fullCellMove(new Coord(x, i), move);
}
// Adds new tile (2 @ 80% chance, or 4 @ 20%) to random empty space on
// board.
void randGen() {
ArrayList<Coord> emptySpaces = new ArrayList<>();
for (int x = 0; x < this.sz; x++)
for (int y = 0; y < this.sz; y++) {
Coord coord = new Coord(x, y);
if (this.get(coord).isReplaceable()) emptySpaces.add(coord);
}
else if (move.equals(Move.DOWN)) {
for (int y = this.sz - 2; y > 0; y--) {
this.tryCellMove(new Coord(i, y), new Coord(i , y + 1));
}
if (!emptySpaces.isEmpty()) {
Coord chosenSpace =
emptySpaces.get(rand.nextInt(emptySpaces.size()));
int value = rand.nextDouble() < 0.8 ? 2 : 4;
this.set(chosenSpace, new Tile(value));
}
}
}
@@ -204,14 +292,18 @@ abstract class Cell {
// Is this moveable?
boolean isMoveable() { return false; }
boolean isReplaceable() { return false;}
boolean isReplaceable() { return false; }
}
// A moveable tile on the board.
class Tile extends Cell {
int n;
boolean flag;
Tile(int n) { this.n = n; }
Tile(int n) {
this.n = n;
this.flag = false;
}
Color col() {
int r = (int)Math.min(255, 20 * (int)(Math.log(this.n) / Math.log(2)));
@@ -227,8 +319,8 @@ class Tile extends Cell {
);
}
boolean isMoveable() { return true;}
boolean isReplaceable() {return false;}
boolean isMoveable() { return true; }
boolean isReplaceable() { return false; }
}
// An empty space on the board.