Greed/Java

From Rosetta Code

Code[edit]

import java.awt.*;
import java.awt.event.*;
import static java.lang.String.format;
import java.util.Random;
import static java.util.stream.IntStream.range;
import javax.swing.*;
 
public class Greed extends JPanel {
final static int PLAYER = -1;
final static int EMPTY = 0;
 
final static int[][] dirs = {{-1, 1}, {0, 1}, {1, 1}, {-1, 0}, {1, 0},
{-1, -1}, {0, -1}, {1, -1}};
 
final int nRows;
final int nCols;
 
Random rand = new Random();
boolean[] availableDirections;
int[][] grid;
int playerRow, playerCol, score, hiScore;
boolean gameOver = true;
 
public Greed() {
setPreferredSize(new Dimension(800, 650));
setBackground(Color.white);
setForeground(Color.lightGray);
setFont(new Font("SansSerif", Font.PLAIN, 18));
setFocusable(true);
 
nRows = 22;
nCols = 61;
availableDirections = new boolean[dirs.length];
initGrid();
 
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (gameOver) {
startNewGame();
repaint();
}
}
});
 
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int k = e.getKeyCode() - KeyEvent.VK_NUMPAD1;
if (k >= 0 && k != 4 && k < 9) { // skip 5 key
move(k > 4 ? --k : k);
}
repaint();
}
});
}
 
void startNewGame() {
initGrid();
if (score > hiScore)
hiScore = score;
score = 0;
playerRow = rand.nextInt(nRows);
playerCol = rand.nextInt(nCols);
grid[playerRow][playerCol] = PLAYER;
availableDirections();
gameOver = false;
}
 
void initGrid() {
grid = new int[nRows][nCols];
for (int r = 0; r < nRows; r++) {
grid[r] = range(0, nCols).map(v -> rand.nextInt(9) + 1).toArray();
}
}
 
void move(int d) {
if (availableDirections[d]) {
grid[playerRow][playerCol] = EMPTY;
 
int x = dirs[d][0];
int y = dirs[d][1];
int c = playerCol + x;
int r = playerRow + y;
int val = grid[r][c];
 
for (int v = 0; v < val - 1; v++, c += x, r += y) {
score += grid[r][c];
grid[r][c] = EMPTY;
}
 
score += grid[r][c];
grid[r][c] = PLAYER;
playerCol = c;
playerRow = r;
 
if (!availableDirections()) {
gameOver = true;
}
}
}
 
void drawGrid(Graphics2D g) {
for (int r = 0; r < nRows; r++) {
for (int c = 0; c < nCols; c++) {
int val = grid[r][c];
if (val > 0)
g.drawString(String.valueOf(val), 30 + c * 12, 40 + r * 25);
else if (val == PLAYER) {
g.setColor(Color.black);
g.fillRect(30 + c * 12, 26 + r * 25, 9, 15);
g.setColor(getForeground());
}
}
}
}
 
boolean availableDirections() {
int countAvailable = 0;
 
for (int d = 0; d < dirs.length; d++) {
availableDirections[d] = false;
 
int x = dirs[d][0];
int y = dirs[d][1];
 
int c = playerCol + x;
int r = playerRow + y;
if (!withinBounds(r, c))
continue;
 
int val = grid[r][c];
 
for (int v = 1; v <= val; v++, c += x, r += y) {
if (!withinBounds(r, c) || grid[r][c] == 0)
break;
if (v == val) {
availableDirections[d] = true;
countAvailable++;
}
}
}
return countAvailable > 0;
}
 
void drawPreview(Graphics2D g) {
g.setXORMode(Color.white);
g.setColor(Color.gray);
for (int d = 0; d < dirs.length; d++) {
if (!availableDirections[d])
continue;
 
int x = dirs[d][0];
int y = dirs[d][1];
 
int c = playerCol + x;
int r = playerRow + y;
 
int val = grid[r][c];
for (int v = 1; v <= val; v++, c += x, r += y) {
g.fillRect(30 + c * 12, 26 + r * 25, 9, 15);
}
}
g.setPaintMode();
}
 
void drawStartScreen(Graphics2D g) {
g.setStroke(new BasicStroke(2.0f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 10.0f, new float[]{5.0f}, 0.0f));
g.setColor(getBackground());
g.fillRect(150, 120, getWidth() - 320, getHeight() - 300);
g.setColor(getForeground());
g.drawRect(170, 140, getWidth() - 360, getHeight() - 340);
 
g.setColor(Color.gray);
g.setFont(new Font("SansSerif", Font.BOLD, 48));
g.drawString("greed", 315, 280);
 
g.setFont(getFont());
g.drawString("(use numpad to move player)", 270, 350);
g.drawString("(click to start)", 328, 380);
}
 
void drawScore(Graphics2D g) {
g.setColor(Color.gray);
g.setFont(getFont());
String s = format("hiscore  %s score  %s", hiScore, score);
g.drawString(s, 30, getHeight() - 40);
}
 
boolean withinBounds(int r, int c) {
return c >= 0 && c < nCols && r >= 0 && r < nRows;
}
 
@Override
public void paintComponent(Graphics gg) {
super.paintComponent(gg);
Graphics2D g = (Graphics2D) gg;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
 
drawGrid(g);
drawScore(g);
 
if (gameOver) {
drawStartScreen(g);
} else {
drawPreview(g);
}
}
 
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("Greed");
f.setResizable(false);
f.add(new Greed(), BorderLayout.CENTER);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}