like two-thirds of the requirements met; interface remaining

This commit is contained in:
steven@devbox 2025-08-02 08:47:27 +00:00
commit 28419157af
13 changed files with 643 additions and 2 deletions

View file

@ -0,0 +1,49 @@
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java application project to get you started.
* For more details on building Java & JVM projects, please refer to https://docs.gradle.org/8.14.3/userguide/building_java_projects.html in the Gradle documentation.
*/
plugins {
// Apply the application plugin to add support for building a CLI application in Java.
application
}
repositories {
// Use Maven Central for resolving dependencies.
mavenCentral()
}
dependencies {
// Use JUnit Jupiter for testing.
testImplementation(libs.junit.jupiter)
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
// This dependency is used by the application.
implementation(libs.guava)
}
// Apply a specific Java toolchain to ease working on different environments.
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
application {
// Define the main class for the application.
mainClass = "org.example.App"
}
tasks.withType<Jar> {
manifest {
attributes["Main-Class"] = "org.example.App"
}
}
tasks.named<Test>("test") {
// Use JUnit Platform for unit tests.
useJUnitPlatform()
}

View file

@ -0,0 +1,177 @@
/*
* This source file was generated by the Gradle 'init' task
*/
package org.example;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Optional;
import java.util.Random;
import java.util.Scanner;
enum PrizeLevel {
NORMAL,
RARE,
EPIC,
LEGENDARY,
EMPTY,
}
class Ball extends Object {
String name;
String colour;
String description;
String prize = null;
String formatPrize() {
return prize == null ? "... nothing" : " " + prize;
}
@Override
public String toString() {
return String.format("%s (%s), it contains %s.", name, colour, formatPrize());
}
public String toDescriptionString() {
return String.format("%s (%s), it contains %s\n%s", name, colour, formatPrize(), description);
}
public Ball(PrizeLevel level, String colour, String desc, String prize) {
switch (level) {
case NORMAL:
this.name = "Normal Prize Ball";
break;
case RARE:
this.name = "Rare Prize Ball";
break;
case EPIC:
this.name = "Epic Prize Ball";
break;
case LEGENDARY:
this.name = "Legendary Prize Ball";
break;
default:
this.name = "Empty Ball";
break;
}
this.colour = colour;
this.description = desc;
this.prize = prize;
}
}
class BallFactory {
PrizeLevel level;
String colour;
String description;
HashMap<String, Integer> prizes;
int numBalls;
public BallFactory(PrizeLevel level, String colour, String description, String[] prizes, int number) {
this.level = level;
this.colour = colour;
this.description = description;
int each = number / prizes.length;
int error = number % prizes.length;
System.out.println("each: " + each + " error: " + error);
HashMap<String, Integer> myPrizes = new HashMap<>();
for (String prize : prizes) {
myPrizes.put(prize, each);
}
for (int i = 0; i < error; i++) {
String randKey = prizes[new Random().nextInt(prizes.length)];
myPrizes.put(randKey, myPrizes.get(randKey) + 1);
}
this.prizes = myPrizes;
System.out.println(this.prizes);
this.numBalls = number;
}
public Ball[] makePrizeBalls() {
Ball[] balls = new Ball[numBalls];
Random r = new Random();
for (int i = 0; i < balls.length; i++) {
ArrayList<String> available = new ArrayList<String>(prizes.keySet());
System.out.println(this.prizes);
int sel = r.nextInt(available.size());
System.out.println(available.get(sel));
balls[i] = new Ball(level, colour, description, available.get(sel));
System.out.println("a ball has been made: " + balls[i]);
prizes.put(available.get(sel), prizes.get(available.get(sel)) - 1);
prizes.entrySet().removeIf(entry -> entry.getValue() <= 0); // NOTE: Here I had to use AI because
// `ConcurrentModificationException` keeps being
// thrown.
}
return balls;
}
class BallMachine extends Object {
Ball[] balls;
public void showBalls() {
for (Ball ball : balls) {
System.out.println(ball);
}
}
}
}
public class App {
public static void main(String[] args) {
String filename;
if (args.length < 1) {
System.out.println("A file name was not specified when starting the application. Provide it here: ");
Scanner sc = new Scanner(System.in);
filename = sc.nextLine();
sc.close();
} else {
filename = args[0];
}
File file = new File(filename);
try {
Scanner fileReader = new Scanner(file);
ArrayList<String> lines = new ArrayList<>();
ArrayList<Ball> balls = new ArrayList<>();
while (fileReader.hasNext()) {
lines.add(fileReader.nextLine());
}
for (int i = 0; i < lines.size(); i++) {
System.out.println("parsing " + lines.get(i));
if (lines.get(i).matches("[A-Z]* [A-Z]* BALL \\[[\\d]*\\]")) {
// A ball collection starts
String[] ballNameParts = lines.get(i).split(" ");
PrizeLevel level = PrizeLevel.valueOf(ballNameParts[0]);
int numBalls = Integer.parseInt(ballNameParts[3].replace("[", "").replace("]", ""));
String colour = lines.get(i + 1);
System.out.println("colour: " + colour);
String desc = lines.get(i + 2);
String prize = null;
if (!(level.equals(PrizeLevel.EMPTY))) {
// ball has prize
prize = lines.get(i + 3);
}
BallFactory factory = new BallFactory(level, colour, desc,
prize.replace("{", "").replace("}", "").split(", "), numBalls);
balls.addAll(Arrays.asList(factory.makePrizeBalls()));
}
}
for (Ball b : balls) {
System.out.println("ball: " + b.toDescriptionString());
}
fileReader.close();
} catch (FileNotFoundException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,14 @@
/*
* This source file was generated by the Gradle 'init' task
*/
package org.example;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class AppTest {
@Test void appHasAGreeting() {
App classUnderTest = new App();
assertNotNull(classUnderTest.getGreeting(), "app should have a greeting");
}
}