mirror of
https://github.com/neon443/RNG_Swift.git
synced 2026-03-11 06:49:12 +00:00
Rewrote basically half the app
+ reamde + noDebug.xcscheme + ui improvements +max die is 100+overflow protextion +fix giant padding in diceview +rewrite rng2() +ui friedlification +rewrite arrCombine
This commit is contained in:
8
README.md
Normal file
8
README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# RNG_Swift
|
||||||
|
|
||||||
|
A fully featured Randomizer written in Swift with UI in SwiftUI!
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- Number generator
|
||||||
|
- Password generator
|
||||||
|
- Die Generator
|
||||||
78
RNG.xcodeproj/xcshareddata/xcschemes/RNG-noDebug.xcscheme
Normal file
78
RNG.xcodeproj/xcshareddata/xcschemes/RNG-noDebug.xcscheme
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "1610"
|
||||||
|
version = "1.7">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES"
|
||||||
|
buildArchitectures = "Automatic">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "A9794C7E2CB70ADA00527984"
|
||||||
|
BuildableName = "RNG.app"
|
||||||
|
BlueprintName = "RNG"
|
||||||
|
ReferencedContainer = "container:RNG.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
shouldAutocreateTestPlan = "YES">
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = ""
|
||||||
|
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "A9794C7E2CB70ADA00527984"
|
||||||
|
BuildableName = "RNG.app"
|
||||||
|
BlueprintName = "RNG"
|
||||||
|
ReferencedContainer = "container:RNG.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "A9794C7E2CB70ADA00527984"
|
||||||
|
BuildableName = "RNG.app"
|
||||||
|
BlueprintName = "RNG"
|
||||||
|
ReferencedContainer = "container:RNG.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
||||||
@@ -12,44 +12,46 @@ struct ContentView: View {
|
|||||||
VStack {
|
VStack {
|
||||||
NavigationSplitView {
|
NavigationSplitView {
|
||||||
List {
|
List {
|
||||||
NavigationLink {
|
Section("Generate...") {
|
||||||
NumberView()
|
NavigationLink {
|
||||||
.navigationTitle("Random Number Generator")
|
NumberView()
|
||||||
} label: {
|
.navigationTitle("Numbers")
|
||||||
HStack {
|
} label: {
|
||||||
Text("Random Number Generator")
|
HStack {
|
||||||
Spacer()
|
Text("Numbers")
|
||||||
Image(systemName: "textformat.123")
|
Spacer()
|
||||||
}
|
Image(systemName: "textformat.123")
|
||||||
}
|
}
|
||||||
NavigationLink {
|
}
|
||||||
DiceView()
|
NavigationLink {
|
||||||
.navigationTitle("Dice")
|
DiceView()
|
||||||
} label: {
|
.navigationTitle("Die")
|
||||||
HStack {
|
} label: {
|
||||||
Text("Dice")
|
HStack {
|
||||||
Spacer()
|
Text("Die")
|
||||||
Image(systemName: "die.face.1")
|
Spacer()
|
||||||
Image(systemName: "die.face.2.fill")
|
Image(systemName: "die.face.1")
|
||||||
Image(systemName: "die.face.3")
|
Image(systemName: "die.face.2.fill")
|
||||||
Image(systemName: "die.face.4.fill")
|
Image(systemName: "die.face.3")
|
||||||
Image(systemName: "die.face.5")
|
Image(systemName: "die.face.4.fill")
|
||||||
Image(systemName: "die.face.6.fill")
|
Image(systemName: "die.face.5")
|
||||||
}
|
Image(systemName: "die.face.6.fill")
|
||||||
}
|
}
|
||||||
NavigationLink {
|
}
|
||||||
PasswordView()
|
NavigationLink {
|
||||||
.navigationTitle("Password")
|
PasswordView()
|
||||||
} label: {
|
.navigationTitle("Passwords")
|
||||||
HStack {
|
} label: {
|
||||||
Text("Password")
|
HStack {
|
||||||
Spacer()
|
Text("Passwords")
|
||||||
Image(systemName: "rectangle.and.pencil.and.ellipsis")
|
Spacer()
|
||||||
|
Image(systemName: "rectangle.and.pencil.and.ellipsis")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.navigationTitle("RNG")
|
||||||
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
}
|
}
|
||||||
.navigationTitle("RNG")
|
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
|
||||||
} detail: {
|
} detail: {
|
||||||
Image(systemName: "dice.fill")
|
Image(systemName: "dice.fill")
|
||||||
}
|
}
|
||||||
@@ -57,3 +59,6 @@ struct ContentView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
ContentView()
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,26 +8,36 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct DiceView: View {
|
struct DiceView: View {
|
||||||
@State var generated: [Int] = [0]
|
@State var advanced: Bool = false
|
||||||
|
@State var generated: [Int] = []
|
||||||
@State var displayDies: [Int] = []
|
@State var displayDies: [Int] = []
|
||||||
@State var displayMultiDieMode = ""
|
@State var displayMultiDieMode = ""
|
||||||
@State var multiDieMode = "plus"
|
@State var multiDieMode = "plus"
|
||||||
@State var result = 0
|
@State var result: UInt = 0
|
||||||
@State var resultDescription = ""
|
@State var resultDescription = ""
|
||||||
@State var history: [Int] = []
|
|
||||||
let columns = [GridItem(.adaptive(minimum: 25, maximum: 75))]
|
let columns = [GridItem(.adaptive(minimum: 25, maximum: 75))]
|
||||||
@State var dies: Double = 2
|
@State var dies: Double = 2
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
List {
|
List {
|
||||||
Section("Number of die") {
|
Section("Number of die") {
|
||||||
|
Toggle(isOn: $advanced) {
|
||||||
|
Text("Advanced Mode")
|
||||||
|
}
|
||||||
HStack {
|
HStack {
|
||||||
Text( String( Int(dies) ) )
|
Text(String(Int(dies)))
|
||||||
.font(.system(size: 25, weight: .bold))
|
.font(.system(size: 20, weight: .heavy))
|
||||||
|
.frame(width: ((dies > 99) ? 40 : (dies > 9) ? 30 : 20))
|
||||||
Divider()
|
Divider()
|
||||||
Text("1")
|
Text("1")
|
||||||
Slider(value: $dies, in: 1...20, step: 1)
|
if advanced {
|
||||||
Text("20")
|
Slider(value: $dies, in: 1...100, step: 1)
|
||||||
|
Text("100")
|
||||||
|
} else {
|
||||||
|
Slider(value: $dies, in: 1...20, step: 1)
|
||||||
|
Text("20")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Section("Multi die mode") {
|
Section("Multi die mode") {
|
||||||
@@ -37,36 +47,36 @@ struct DiceView: View {
|
|||||||
}.pickerStyle(SegmentedPickerStyle())
|
}.pickerStyle(SegmentedPickerStyle())
|
||||||
}
|
}
|
||||||
Section("Visual") {
|
Section("Visual") {
|
||||||
HStack {
|
if displayDies.isEmpty {
|
||||||
Spacer()
|
Text("Tap Generate to get started!")
|
||||||
if displayDies.isEmpty {
|
.font(.headline)
|
||||||
Text("Results are visualised here when you press the generate button")
|
.fontWeight(.heavy)
|
||||||
.font(.subheadline)
|
.frame(alignment: .center)
|
||||||
} else {
|
} else {
|
||||||
LazyVGrid(columns: columns, spacing: 10) {
|
LazyVGrid(columns: columns, spacing: 2.5) {
|
||||||
ForEach(0..<displayDies.count, id: \.self) { index in
|
ForEach(0..<displayDies.count, id: \.self) { index in
|
||||||
Image(systemName: "die.face.\(displayDies[index])")
|
Image(systemName: "die.face.\(displayDies[index])")
|
||||||
|
.resizable()
|
||||||
|
.scaledToFit()
|
||||||
|
.frame(width: 40, height: 40)
|
||||||
|
if index != displayDies.count-1 {
|
||||||
|
Image(systemName: displayMultiDieMode)
|
||||||
.resizable()
|
.resizable()
|
||||||
.scaledToFit()
|
.scaledToFit()
|
||||||
.frame(width: 50, height: 50)
|
.frame(width: 15, height: 15)
|
||||||
if index != displayDies.count-1 {
|
|
||||||
Image(systemName: displayMultiDieMode)
|
|
||||||
.resizable()
|
|
||||||
.scaledToFit()
|
|
||||||
.frame(width: 10, height: 10)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.padding()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Text(String(result))
|
Text(String(result))
|
||||||
.font(.system(size: 75, weight: .bold))
|
.font(.system(size: 50, weight: .bold))
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
.frame(height: 50)
|
.frame(height: 40)
|
||||||
Text(resultDescription)
|
Text(resultDescription)
|
||||||
.frame(height: 20)
|
.frame(height: 10)
|
||||||
|
.font(.system(size: 10))
|
||||||
Button {
|
Button {
|
||||||
generated = rngN6DieArr(dies: Int(dies))
|
generated = rngN6DieArr(dies: Int(dies))
|
||||||
displayDies = generated
|
displayDies = generated
|
||||||
@@ -90,12 +100,12 @@ func describeResult(inp: [Int], combineMode: String) -> String {
|
|||||||
var result = ""
|
var result = ""
|
||||||
var symbol = ""
|
var symbol = ""
|
||||||
if inp.isEmpty {
|
if inp.isEmpty {
|
||||||
return "0"
|
return ""
|
||||||
} else {
|
} else {
|
||||||
if combineMode == "plus" {
|
if combineMode == "plus" {
|
||||||
symbol = " + "
|
symbol = "+"
|
||||||
} else if combineMode == "multiply" {
|
} else if combineMode == "multiply" {
|
||||||
symbol = " x "
|
symbol = "x"
|
||||||
}
|
}
|
||||||
for i in 0...len {
|
for i in 0...len {
|
||||||
if i == len {
|
if i == len {
|
||||||
@@ -104,7 +114,6 @@ func describeResult(inp: [Int], combineMode: String) -> String {
|
|||||||
result += String(inp[i]) + symbol
|
result += String(inp[i]) + symbol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result += " = " + String(arrCombine(arr: inp, combineMode: combineMode))
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,36 +5,17 @@
|
|||||||
// Created by Nihaal on 09/10/2024.
|
// Created by Nihaal on 09/10/2024.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//fix date created
|
|
||||||
//TODO: readd ios 16 support
|
|
||||||
//TODO: try to use inject
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct NumberView: View {
|
struct NumberView: View {
|
||||||
@State var low: String = "1"
|
@State var low: String = "1"
|
||||||
@State var high: String = "10"
|
@State var high: String = "10"
|
||||||
@State var exclude: String = "none"
|
@State var exclude: String = "none"
|
||||||
@State var generated = "5"
|
@State var generated = ""
|
||||||
@State var prevGen = ""
|
@State var prevGen = ""
|
||||||
@State var generatedInt: Int = 0
|
@State var generatedInt: Int = 0
|
||||||
@State var prevGenInt: Int = 0
|
@State var prevGenInt: Int = 0
|
||||||
@State var dispResult = 5
|
@State var dispResult = 0
|
||||||
var body: some View {
|
var body: some View {
|
||||||
List {
|
List {
|
||||||
HStack {
|
HStack {
|
||||||
@@ -65,30 +46,18 @@ struct NumberView: View {
|
|||||||
}
|
}
|
||||||
Section("Description") {
|
Section("Description") {
|
||||||
Text(describeInputs(min: low, max: high, exclude: exclude))
|
Text(describeInputs(min: low, max: high, exclude: exclude))
|
||||||
|
.font(.headline)
|
||||||
|
.fontWeight(.heavy)
|
||||||
|
.frame(alignment: .center)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Text(String(dispResult))
|
Text(generated)
|
||||||
.font(.system(size: 75, weight: .bold))
|
.font(.system(size: 50, weight: .bold))
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
.frame(height: 50)
|
.frame(height: 40)
|
||||||
Button {
|
Button {
|
||||||
prevGen = generated
|
prevGen = generated
|
||||||
generated = rng2(min: low, max: high, exclude: exclude)
|
generated = rng3(min: low, max: high, exclude: exclude)
|
||||||
prevGenInt = Int(prevGen)!
|
|
||||||
generatedInt = Int(generated)!
|
|
||||||
if prevGenInt < generatedInt {
|
|
||||||
for _ in prevGenInt...generatedInt {
|
|
||||||
dispResult += 1
|
|
||||||
//sleep( UInt32( 1 / (generatedInt - prevGenInt) ) )
|
|
||||||
}
|
|
||||||
} else if prevGenInt > generatedInt {
|
|
||||||
for _ in generatedInt...prevGenInt {
|
|
||||||
dispResult -= 1
|
|
||||||
//sleep( UInt32( 1 / (prevGenInt - generatedInt) ) )
|
|
||||||
}
|
|
||||||
} else if prevGenInt == generatedInt {
|
|
||||||
dispResult = generatedInt
|
|
||||||
}
|
|
||||||
} label: {
|
} label: {
|
||||||
Text("Generate")
|
Text("Generate")
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
@@ -96,26 +65,26 @@ struct NumberView: View {
|
|||||||
}
|
}
|
||||||
.buttonStyle(BorderedProminentButtonStyle())
|
.buttonStyle(BorderedProminentButtonStyle())
|
||||||
.cornerRadius(15)
|
.cornerRadius(15)
|
||||||
.padding(.bottom)
|
.padding(.vertical)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func describeInputs(min: String, max: String, exclude: String) -> String {
|
func describeInputs(min: String, max: String, exclude: String) -> String {
|
||||||
let validExcludes = ["start", "end", "both", "none"]
|
let validExcludes = ["start", "none", "end", "both"]
|
||||||
guard validExcludes.contains(exclude) else {
|
guard validExcludes.contains(exclude) else {
|
||||||
print("invalid exclude: " + exclude)
|
print("invalid exclude: " + exclude)
|
||||||
return "invalid exclude: " + exclude
|
return "invalid exclude: " + exclude
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = "Any number from "
|
var result = "Any number from "
|
||||||
result += min != "" ? min : "_"
|
result += min
|
||||||
result += " to "
|
result += " to "
|
||||||
result += max != "" ? max : "_"
|
result += max
|
||||||
|
|
||||||
if min == "" || max == "" {
|
if min == "" || max == "" {
|
||||||
return "Enter values above."
|
return "Enter values above."
|
||||||
} else {
|
}
|
||||||
switch exclude {
|
switch exclude {
|
||||||
case "start":
|
case "start":
|
||||||
result += ", excluding \(min)"
|
result += ", excluding \(min)"
|
||||||
case "end":
|
case "end":
|
||||||
@@ -126,48 +95,31 @@ func describeInputs(min: String, max: String, exclude: String) -> String {
|
|||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
result = "invalid 'exclude'"
|
result = "invalid 'exclude'"
|
||||||
}
|
|
||||||
}
|
}
|
||||||
result += "."
|
return result + "."
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum rng2Errors: Error {
|
func rng3(min: String, max: String, exclude: String) -> String {
|
||||||
case h
|
var newMin = Int(min)!
|
||||||
}
|
var newMax = Int(max)!
|
||||||
|
guard newMin <= newMax else {
|
||||||
func rng2(min: String, max: String, exclude: String) -> String {
|
return "Invalid inputs"
|
||||||
guard min != "" || max != "" else {
|
|
||||||
return "Enter values above."
|
|
||||||
}
|
}
|
||||||
guard var minInt = Int(min) else {
|
guard newMin != newMax else {
|
||||||
print("invalid min")
|
return "No numbers"
|
||||||
return "-1"
|
|
||||||
}
|
}
|
||||||
guard var maxInt = Int(max), maxInt >= minInt else {
|
guard newMin + 1 != newMax else {
|
||||||
print("invalid max or is less than min")
|
return "No numbers"
|
||||||
return "-1"
|
|
||||||
}
|
}
|
||||||
guard exclude != "both", min != max else {
|
|
||||||
print("excluding both but min == max")
|
|
||||||
return "No possible numbers, both bounds equal."
|
|
||||||
}
|
|
||||||
let minIntPlus1 = minInt + 1
|
|
||||||
guard exclude != "both", minIntPlus1 != maxInt else {
|
|
||||||
print("excluding both but min +1 == max")
|
|
||||||
return "No possible numbers."
|
|
||||||
}
|
|
||||||
var generated = 0
|
|
||||||
if exclude == "both" {
|
if exclude == "both" {
|
||||||
maxInt -= 1
|
newMax -= 1
|
||||||
minInt += 1
|
newMin += 1
|
||||||
} else if exclude == "start" {
|
} else if exclude == "start" {
|
||||||
minInt += 1
|
newMin += 1
|
||||||
} else if exclude == "end" {
|
} else if exclude == "end" {
|
||||||
maxInt -= 1
|
newMax -= 1
|
||||||
}
|
}
|
||||||
generated = rng(min: minInt, max: maxInt)
|
return String(rng(min: newMin, max: newMax))
|
||||||
return String(generated)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ import SwiftUI
|
|||||||
struct PasswordView: View {
|
struct PasswordView: View {
|
||||||
@State var selectedOptions: [PassOption] = []
|
@State var selectedOptions: [PassOption] = []
|
||||||
let options: [PassOption] = [
|
let options: [PassOption] = [
|
||||||
PassOption(name: "0-9", chars: Array("0123456789")),
|
PassOption(name: "Digits", chars: Array("0123456789")),
|
||||||
PassOption(name: "a-z", chars: Array("abcdefghijklmnopqrstuvwxyz")),
|
PassOption(name: "Lowercase characters", chars: Array("abcdefghijklmnopqrstuvwxyz")),
|
||||||
PassOption(name: "A-Z", chars: Array("ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
|
PassOption(name: "Uppercase characters", chars: Array("ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
|
||||||
]
|
]
|
||||||
@State var presetLen = 4
|
@State var presetLen = 4
|
||||||
@State var customLen = 8
|
@State var customLen: Int = 0
|
||||||
@State var generated = ""
|
@State var generated = ""
|
||||||
@State var result = ""
|
@State var result = ""
|
||||||
@State var history: [Int] = []
|
@State var history: [Int] = []
|
||||||
@@ -23,16 +23,6 @@ struct PasswordView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
List {
|
List {
|
||||||
Text("Hello, world!")
|
|
||||||
.font(.largeTitle)
|
|
||||||
.foregroundColor(.white)
|
|
||||||
.padding()
|
|
||||||
.background(Color.blue)
|
|
||||||
.padding()
|
|
||||||
.background(Color.mint)
|
|
||||||
.padding()
|
|
||||||
.background(Color.green)
|
|
||||||
|
|
||||||
Section("Include") {
|
Section("Include") {
|
||||||
ForEach(options) { option in
|
ForEach(options) { option in
|
||||||
Toggle(isOn: Binding(
|
Toggle(isOn: Binding(
|
||||||
@@ -59,35 +49,30 @@ struct PasswordView: View {
|
|||||||
Text("Custom: \(customLen)").tag(-1)
|
Text("Custom: \(customLen)").tag(-1)
|
||||||
}
|
}
|
||||||
.pickerStyle(SegmentedPickerStyle())
|
.pickerStyle(SegmentedPickerStyle())
|
||||||
|
|
||||||
|
if presetLen == -1 {
|
||||||
|
TextField("Custom", value: $customLen, formatter: NumberFormatter())
|
||||||
|
.keyboardType(.numberPad)
|
||||||
|
.frame(width: 50)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if presetLen == -1 {
|
|
||||||
TextField("Custom", value: $customLen, formatter: NumberFormatter())
|
|
||||||
.keyboardType(.numberPad)
|
|
||||||
.frame(width: 50)
|
|
||||||
}
|
|
||||||
|
|
||||||
Text(String(result))
|
|
||||||
.font(.system(size: 75, weight: .bold))
|
|
||||||
.foregroundColor(.gray)
|
|
||||||
.frame(height: 50)
|
|
||||||
|
|
||||||
Text(String(generated))
|
|
||||||
.font(.system(size: 75, weight: .bold))
|
|
||||||
.foregroundColor(.gray)
|
|
||||||
.frame(height: 50)
|
|
||||||
|
|
||||||
Button {
|
|
||||||
generated = genPass(selectdOpts: selectedOptions, len: (presetLen == -1 ? customLen : presetLen))
|
|
||||||
} label: {
|
|
||||||
Text("Generate")
|
|
||||||
.padding(.horizontal)
|
|
||||||
.font(.system(size: 25, weight: .bold))
|
|
||||||
}
|
|
||||||
.buttonStyle(BorderedProminentButtonStyle())
|
|
||||||
.cornerRadius(15)
|
|
||||||
.padding(.vertical)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Text(String(generated))
|
||||||
|
.font(.system(size: 50, weight: .bold))
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
.frame(height: 40)
|
||||||
|
|
||||||
|
Button {
|
||||||
|
generated = genPass(selectdOpts: selectedOptions, len: (presetLen == -1 ? customLen : presetLen))
|
||||||
|
} label: {
|
||||||
|
Text("Generate")
|
||||||
|
.padding(.horizontal)
|
||||||
|
.font(.system(size: 25, weight: .bold))
|
||||||
|
}
|
||||||
|
.buttonStyle(BorderedProminentButtonStyle())
|
||||||
|
.cornerRadius(15)
|
||||||
|
.padding(.vertical)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,7 +88,7 @@ struct PassOption: Identifiable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func genPass(selectdOpts: [PassOption], len: Int) -> String {
|
func genPass(selectdOpts: [PassOption], len: Int) -> String {
|
||||||
let characters = selectdOpts.flatMap { $0.chars }
|
let characters = selectdOpts.flatMap { $0.chars }
|
||||||
|
|
||||||
guard !(characters.isEmpty) else {
|
guard !(characters.isEmpty) else {
|
||||||
print("characters empty")
|
print("characters empty")
|
||||||
|
|||||||
@@ -35,15 +35,22 @@ func totalDoubleArr(arr: [Double]) -> Double {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// array combiner, adds or multiplies all ints in an array
|
// array combiner, adds or multiplies all ints in an array
|
||||||
func arrCombine(arr: [Int], combineMode: String) -> Int {
|
func arrCombine(arr: [Int], combineMode: String) -> UInt {
|
||||||
var output = 0
|
var newArr: [UInt] = []
|
||||||
|
for i in 0...(arr.count-1) {
|
||||||
|
newArr.append(UInt(arr[i]))
|
||||||
|
}
|
||||||
|
var output: UInt = 0
|
||||||
if combineMode == "plus" {
|
if combineMode == "plus" {
|
||||||
for num in arr {
|
for num in newArr {
|
||||||
output += num
|
output += num
|
||||||
}
|
}
|
||||||
} else if combineMode == "multiply" {
|
} else if combineMode == "multiply" {
|
||||||
output = 1
|
output = 1
|
||||||
for num in arr {
|
for num in newArr {
|
||||||
|
guard output <= UInt.max / num else {
|
||||||
|
return UInt.max //cap at uint.max 2^64
|
||||||
|
}
|
||||||
output *= num
|
output *= num
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -53,11 +60,8 @@ func arrCombine(arr: [Int], combineMode: String) -> Int {
|
|||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func rng(min: Int, max: Int) -> Int {
|
func rng(min: Int, max: Int) -> Int {
|
||||||
var rng = 0
|
return Int.random(in: min...max)
|
||||||
rng = Int.random(in: min...max)
|
|
||||||
return rng
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func rng6Die() -> Int {
|
func rng6Die() -> Int {
|
||||||
@@ -69,6 +73,7 @@ func rngCDie(min: Int, max: Int) -> Int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func rngN6DieArr(dies: Int) -> [Int] {
|
func rngN6DieArr(dies: Int) -> [Int] {
|
||||||
|
guard dies > 0 else { return [] }
|
||||||
var output: [Int] = []
|
var output: [Int] = []
|
||||||
for _ in 1...dies {
|
for _ in 1...dies {
|
||||||
output.append(rng6Die())
|
output.append(rng6Die())
|
||||||
|
|||||||
Reference in New Issue
Block a user