Files
diehammer/Bunch-O--Dice/Model/Dice.swift
T
2026-09-07 10:07:07 -05:00

313 lines
7.4 KiB
Swift

//
// Dice.swift
// Bunch O' Dice
//
// Created by Rory Hinnen on 22/2/20.
//
import Foundation
struct Dice {
// MARK: Private
private var d6: Int {
get {
return Int.random(in: 1...6)
}
}
// MARK: Enums
enum DiceType: Int, CaseIterable{
case one = 1
case two = 2
case three = 3
case four = 4
case five = 5
case six = 6
}
enum RollModifiers: Int {
case negative = -1
case none = 0
case positive = 1
func add() -> RollModifiers {
switch self {
case .negative:
return RollModifiers.none
case .none:
return RollModifiers.positive
case .positive:
return RollModifiers.positive
}
}
func remove() -> RollModifiers {
switch self {
case .negative:
return RollModifiers.negative
case .none:
return RollModifiers.negative
case .positive:
return RollModifiers.none
}
}
}
// MARK: Variables
var one = 0
var two = 0
var three = 0
var four = 0
var five = 0
var six = 0
// MARK: Roll controllers
// clear and roll the die
mutating func roll(howMany: Int) {
clear()
var y = howMany
while y > 0 {
switch d6 {
case 1:
one += 1
case 2:
two += 1
case 3:
three += 1
case 4:
four += 1
case 5:
five += 1
default:
six += 1
}
y -= 1
}
}
// calculate basic roll
func total(cutoff: Int, modifier: Dice.RollModifiers) -> Int {
var total = six
switch modifier {
case .none:
switch cutoff {
case 5:
total += five
case 4:
total += four + five
case 3:
total += three + four + five
case 2:
total += two + three + four + five
default:
break
}
case .negative:
switch cutoff {
case 4:
total += five
case 3:
total += four + five
case 2:
total += three + four + five
case 1:
total += two + three + four + five
default:
break
}
case .positive:
switch cutoff {
case 6:
total += five
case 5:
total += four + five
case 4:
total += three + four + five
case 3, 2:
total += two + three + four + five
default:
break
}
}
return total
}
// Calculate different rolls
func hit(die: Int, cutoff: Int, modifier: Int) -> Int {
return total(cutoff: cutoff, modifier: Dice.RollModifiers(rawValue: modifier) ?? .none)
}
func wound(die: Int, mortal: Bool, cutoff: Int, modifier: Int) -> Int {
if mortal {
return total(cutoff: 2, modifier: Dice.RollModifiers(rawValue: modifier) ?? .none)
} else {
return total(cutoff: cutoff, modifier: Dice.RollModifiers(rawValue: modifier) ?? .none)
}
}
func armour(die: Int, invulnerable: Bool, save: Int, armourPenetration: Int) -> Int {
var total = 0
switch invulnerable ? save : (save - armourPenetration) {
case 7...:
total = six + five + four + three + two + one
case 6:
total = five + four + three + two + one
case 5:
total = four + three + two + one
case 4:
total = three + two + one
case 3:
total = two + one
default:
total = one
}
return total
}
// MARK: roll utilities
// Utility functions
mutating func clear() {
one = 0
two = 0
three = 0
four = 0
five = 0
six = 0
}
mutating func add(pool: Dice) {
one += pool.one
two += pool.two
three += pool.three
four += pool.four
five += pool.five
six += pool.six
}
func value(which: DiceType) -> Int {
switch which {
case .one:
return one
case .two:
return two
case .three:
return three
case .four:
return four
case .five:
return five
case .six:
return six
}
}
// MARK: Extra
mutating func increment(die: DiceType) {
switch die {
case .one:
one += 1
case .two:
two += 1
case .three:
three += 1
case .four:
four += 1
case .five:
five += 1
case .six:
six += 1
}
}
mutating func decrement(die: DiceType) {
switch die {
case .one:
if one > 0 {
one -= 1
}
case .two:
if two > 0 {
two -= 1
}
case .three:
if three > 0 {
three -= 1
}
case .four:
if four > 0 {
four -= 1
}
case .five:
if five > 0 {
five -= 1
}
case .six:
if six > 0 {
six -= 1
}
}
}
mutating func reroll(dice: DiceType) {
var rerolls = Dice()
switch dice {
case .one:
rerolls.roll(howMany: one)
one = 0
self.add(pool: rerolls)
case .two:
rerolls.roll(howMany: two)
two = 0
self.add(pool: rerolls)
case .three:
rerolls.roll(howMany: three)
three = 0
self.add(pool: rerolls)
case .four:
rerolls.roll(howMany: four)
four = 0
self.add(pool: rerolls)
case .five:
rerolls.roll(howMany: five)
five = 0
self.add(pool: rerolls)
case .six:
rerolls.roll(howMany: six)
six = 0
self.add(pool: rerolls)
}
}
mutating func rerollBelow(cutoff: Int) {
var count = 0
for faceValue in 1..<cutoff {
guard let face = DiceType(rawValue: faceValue) else { continue }
count += value(which: face)
switch face {
case .one: one = 0
case .two: two = 0
case .three: three = 0
case .four: four = 0
case .five: five = 0
case .six: six = 0
}
}
var rerolls = Dice()
rerolls.roll(howMany: count)
add(pool: rerolls)
}
mutating func blowup(dice: DiceType) {
var rolls = Dice()
if dice == .six {
rolls.roll(howMany: six)
self.add(pool: rolls)
} else if dice == .five {
rolls.roll(howMany: six + five)
self.add(pool: rolls)
}
}
}