Skip to content

Commit

Permalink
Merge branch 'release-0.2.0-alpha'
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin Karstad committed Apr 3, 2021
2 parents e22279e + 54565a6 commit d27a895
Show file tree
Hide file tree
Showing 9 changed files with 450 additions and 267 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>dev.thearcticgiant</groupId>
<artifactId>dice4j</artifactId>
<version>0.1.1-alpha-SNAPSHOT</version>
<version>0.2.0-alpha-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down
62 changes: 62 additions & 0 deletions src/main/java/dev/thearcticgiant/dice4j/Bonus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package dev.thearcticgiant.dice4j;

/**
* A static numerical bonus to a roll.
* Once created, its value cannot be changed, and calls to <code>roll</code> have no effect.
*/
public class Bonus implements Rollable{
public final int value;

public Bonus(int value){
this.value = value;
}

/**
* Return this instance of <code>Bonus</code>, has no effect.
* @return This instance.
*/
@Override
public Bonus roll(){
return this;
}

@Override
public int read(){
return value;
}

/**
* Has no effect.
*/
@Override
public void lock(){}

/**
* Always returns true.
* @return True
*/
@Override
public boolean isLocked(){
return true;
}

@Override
public String getName(){
return Integer.toString(value);
}

@Override
public String getMarkdownName(){
return getName();
}

@Override
public String toString(){
return Integer.toString(value);
}

@Override
public String toMarkdownString(){
return toString();
}
}
151 changes: 127 additions & 24 deletions src/main/java/dev/thearcticgiant/dice4j/Dice.java
Original file line number Diff line number Diff line change
@@ -1,33 +1,136 @@
package dev.thearcticgiant.dice4j;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Dice{
private static Matcher matcher = Pattern.compile("(?:(?<count>[+-]?\\d++)?d(?<sides>[+-]?\\d++))?(?<bonus>[+-]?\\d++)?").matcher("");
public static Roll roll(String exp){
if(!matcher.reset(exp).matches()) throw new RuntimeException("invalid dice expression");
String countStr = matcher.group("count"),
sidesStr = matcher.group("sides"),
bonusStr = matcher.group("bonus");

if(countStr == null){
if(sidesStr == null) countStr = sidesStr = "0";
else countStr = "1";
import java.util.Iterator;
import java.util.Random;
import java.util.List;

public class Dice implements Rollable{
public final List<Die> dice;
public final int count, sides;
private boolean locked = false;

/**
* Construct a roll of the format xdy.
* Random rolls are determined by the provided Random.
* @param count A positive integer indicating number of dice rolled.
* @param sides A positive integer indicating the number of sides on each die.
* @param random The Random object for making rolls.
* @throws RuntimeException if count or sides is non-positive.
*/
public Dice(int count, int sides, Random random){
if(count <= 0) throw new RuntimeException("count must be positive");
if(sides <= 0) throw new RuntimeException("sides must be positive");
this.count = count;
this.sides = sides;

final Die[] dice = new Die[count];
for(int i=0; i<count; i++) dice[i] = new Die(sides, random);
this.dice = List.of(dice);
}

/**
* Construct a roll of the format xdy+z.
* @param count A positive integer indicating number of dice rolled.
* @param sides A positive integer indicating the number of sides on each die.
* @throws RuntimeException if count or sides is non-positive.
*/
public Dice(int count, int sides){
this(count, sides, new Random());
}

/**
* Construct a seeded roll of the format xdy+z.
* @param count A positive integer indicating number of dice rolled.
* @param sides A positive integer indicating the number of sides on each die.
* @param seed The seed for the generation of rolls.
* @throws RuntimeException if count or sides is non-positive.
*/
public Dice(int count, int sides, long seed){
this(count, sides, new Random(seed));
}

@Override
public int read(){
int total = 0;
for(Die die : dice){
total+=die.read();
}
return total;
}

if(bonusStr == null) bonusStr = "0";
@Override
public Dice roll(){
if(!locked) for(Die die : dice) die.roll();
return this;
}

final int
count = Integer.parseInt(countStr),
sides = Integer.parseInt(sidesStr),
bonus = Integer.parseInt(bonusStr);
return roll(count, sides, bonus);
@Override
public final void lock(){
locked = true;
for(Die die : dice) die.lock();
}
public static Roll roll(int count, int sides, int bonus){
return new Roll(count, sides, bonus);

@Override
public final boolean isLocked(){
return locked;
}
public static Roll roll(int count, int sides){
return new Roll(count, sides);

/**
* The count and sides of this Dice in the format xdy.
* @return The name of this Dice.
*/
@Override
public String getName(){
return String.format("%dd%d", count, sides);
}

/**
* Equivalent to <code>getName</code> with the "d" bolded.
* @return The markdown formatted name of this Dice.
*/
@Override
public String getMarkdownName(){
return String.format("%d**d**%d", count, sides);
}

/**
* A string representation of the roll.
* The equation is always equal to total().
* In the format "[a, b, c, ...] = t".
* @return A string representing the rolled dice.
*/
@Override
public String toString(){
StringBuilder builder = new StringBuilder();
builder.append('[');
for(Iterator<Die> i = dice.iterator(); i.hasNext();){
builder.append(i.next().read());
if(i.hasNext()) builder.append(", ");
}
builder.append(']');
return builder.toString();
}

/**
* Equivalent to toString, with any max rolls bolded.
* @return A markdown formatted string representing the rolled dice.
*/
@Override
public String toMarkdownString(){
StringBuilder builder = new StringBuilder();
builder.append('[');
for(Iterator<Die> i = dice.iterator(); i.hasNext();){
int die = i.next().read();

if(die == sides)
builder.append("**")
.append(die)
.append("**");
else builder.append(die);

if(i.hasNext()) builder.append(", ");
}
builder.append(']');
return builder.toString();
}
}
69 changes: 46 additions & 23 deletions src/main/java/dev/thearcticgiant/dice4j/Die.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,60 +4,83 @@

public class Die implements Rollable{
public final int sides;
private boolean locked;
private int roll;

private final Random random;

/**
* Construct a new die, using a provided Random object.
* @param sides The number of sides.
* @param random The Random used to generate rolls.
*/
public Die(int sides, Random random){
this.sides = sides;
this.random = random;

roll();
}

/**
* Construct and roll a new die with a specific random seed.
* @param sides The number of sides.
* @param seed The seed used to create the internal Random object.
* @throws RuntimeException if sides is non-positive.
*/
public Die(int sides, long seed){
this(sides, new Random(seed));
}

/**
* Construct and roll a new die.
* Construct a new die.
* @param sides The number of sides.
* @throws RuntimeException if sides is non-positive.
*/

public Die(int sides){
this(sides, new Random());
}

private Die(int sides, Random random){
this.sides = sides;
this.random = random;

if(sides <= 0) throw new RuntimeException("sides must be positive");

roll();
}

/**
* Re-roll this die;
* @return The new result;
*/
public int roll(){
return roll = random.nextInt(sides)+1;
@Override
public Die roll(){
if(!locked) roll = random.nextInt(sides)+1;
return this;
}

@Override
public int read(){
return roll;
}

public int fudge(int roll){
return this.roll = roll;
@Override
public final void lock(){
locked = true;
}

@Override
public final boolean isLocked(){
return locked;
}

@Override
public String getName(){
return String.format("d%d", sides);
return String.format("1d%d", sides);
}

@Override
public String getMarkdownName(){
return String.format("1**d**%d", sides);
}

@Override
public String toString(){
return String.format("%s (%d)", getName(), roll);
return Integer.toString(roll);
}

@Override
public String toMarkdownString(){
StringBuilder builder = new StringBuilder();

if(roll >= sides) builder.append("**").append(roll).append("**");
else builder.append(roll);

return builder.toString();
}
}
Loading

0 comments on commit d27a895

Please sign in to comment.