【问题标题】:I am trying to create a base function to use on multiple randomisation in a program (Beginner level)我正在尝试创建一个基本函数以用于程序中的多个随机化(初级)
【发布时间】:2022-10-02 02:09:50
【问题描述】:

Dice Roller

例如在这个应用程序上(我只是为了 D&D 的角色创建需要而创建的),当你按下 \"Roll\" 时,程序会滚动 3 次 \"d6 (6 面骰子)\" 并将它们相加,并添加对相应的“Stat”数组求和,它会执行 3 次,然后从数组中取最高值作为结果。

我这里的菜鸟功能代码在这里;

    func rollStr() {

    strArray.removeAll()
    
    let r1 = Int.random(in: 1...6)
    let r2 = Int.random(in: 1...6)
    let r3 = Int.random(in: 1...6)
    let r4 = Int.random(in: 1...6)
    let r5 = Int.random(in: 1...6)
    let r6 = Int.random(in: 1...6)
    let r7 = Int.random(in: 1...6)
    let r8 = Int.random(in: 1...6)
    let r9 = Int.random(in: 1...6)

    strArray.append(r1 + r2 + r3)
    strArray.append(r4 + r5 + r6)
    strArray.append(r7 + r8 + r9)
    
    strStat = strArray.max()!

}

我没有设法只声明 3 个值并滚动 3 次,所以我决定用 9 个变量来做。无论如何,正如您在上面看到的,此函数中有 \"strArray\" 和 \"strStat\"。我必须为每个不同的统计数据编写 6 个该函数的副本。我尝试使用可编辑的功能,例如;

    func rollStat(arrayNumber: Int, statNumber: Int) {
    
    var allArrays = [strArray, dexArray, consArray, intArray, wisArray, chaArray]
    var allStats = [strStat, dexStat, consStat, intStat, wisStat, chaStat]
    

    allArrays[arrayNumber].removeAll()
    
    let r1 = Int.random(in: 1...6)
    let r2 = Int.random(in: 1...6)
    let r3 = Int.random(in: 1...6)
    let r4 = Int.random(in: 1...6)
    let r5 = Int.random(in: 1...6)
    let r6 = Int.random(in: 1...6)
    let r7 = Int.random(in: 1...6)
    let r8 = Int.random(in: 1...6)
    let r9 = Int.random(in: 1...6)

    allArrays[arrayNumber].append(r1 + r2 + r3)
    allArrays[arrayNumber].append(r4 + r5 + r6)
    allArrays[arrayNumber].append(r7 + r8 + r9)
    
    allStats[statNumber] = allArrays[arrayNumber].max()!

}

并想将该函数称为 \"rollStat(arrayNumber: 1, statNumber: 1)\" 以使用一个基本函数来调用我需要的值,而不是使用多个副本,但我无法使其工作。我在这里做错了什么?

正如我所说的,我实现了我所需要的,该程序可以工作,但如果可能的话,我想知道只用一个函数来完成它的技巧。

如果您想了解有关前几行的任何信息,我将粘贴下面的所有代码。提前致谢。

struct ContentView: View {

// MARK: PROPERTY

@State private var strArray:[Int] = [0,0,0]
@State private var dexArray:[Int] = [0,0,0]
@State private var consArray:[Int] = [0,0,0]
@State private var intArray:[Int] = [0,0,0]
@State private var wisArray:[Int] = [0,0,0]
@State private var chaArray:[Int] = [0,0,0]

@State private var strStat = 0
@State private var dexStat = 0
@State private var consStat = 0
@State private var intStat = 0
@State private var wisStat = 0
@State private var chaStat = 0



// MARK: METHOD

func rollStr() {

    strArray.removeAll()
    
    let r1 = Int.random(in: 1...6)
    let r2 = Int.random(in: 1...6)
    let r3 = Int.random(in: 1...6)
    let r4 = Int.random(in: 1...6)
    let r5 = Int.random(in: 1...6)
    let r6 = Int.random(in: 1...6)
    let r7 = Int.random(in: 1...6)
    let r8 = Int.random(in: 1...6)
    let r9 = Int.random(in: 1...6)

    strArray.append(r1 + r2 + r3)
    strArray.append(r4 + r5 + r6)
    strArray.append(r7 + r8 + r9)
    
    strStat = strArray.max()!

}

func rollDex() {
    
    dexArray.removeAll()
    
    let r1 = Int.random(in: 1...6)
    let r2 = Int.random(in: 1...6)
    let r3 = Int.random(in: 1...6)
    let r4 = Int.random(in: 1...6)
    let r5 = Int.random(in: 1...6)
    let r6 = Int.random(in: 1...6)
    let r7 = Int.random(in: 1...6)
    let r8 = Int.random(in: 1...6)
    let r9 = Int.random(in: 1...6)
    
    dexArray.append(r1 + r2 + r3)
    dexArray.append(r4 + r5 + r6)
    dexArray.append(r7 + r8 + r9)
    
    dexStat = dexArray.max()!
    
}

func rollCons() {
    
    consArray.removeAll()
    
    let r1 = Int.random(in: 1...6)
    let r2 = Int.random(in: 1...6)
    let r3 = Int.random(in: 1...6)
    let r4 = Int.random(in: 1...6)
    let r5 = Int.random(in: 1...6)
    let r6 = Int.random(in: 1...6)
    let r7 = Int.random(in: 1...6)
    let r8 = Int.random(in: 1...6)
    let r9 = Int.random(in: 1...6)
    
    consArray.append(r1 + r2 + r3)
    consArray.append(r4 + r5 + r6)
    consArray.append(r7 + r8 + r9)
    
    consStat = consArray.max()!
    
}

func rollInt() {
    
    intArray.removeAll()
    
    let r1 = Int.random(in: 1...6)
    let r2 = Int.random(in: 1...6)
    let r3 = Int.random(in: 1...6)
    let r4 = Int.random(in: 1...6)
    let r5 = Int.random(in: 1...6)
    let r6 = Int.random(in: 1...6)
    let r7 = Int.random(in: 1...6)
    let r8 = Int.random(in: 1...6)
    let r9 = Int.random(in: 1...6)
    
    intArray.append(r1 + r2 + r3)
    intArray.append(r4 + r5 + r6)
    intArray.append(r7 + r8 + r9)
    
    intStat = intArray.max()!
    
}

func rollWis() {
    
    wisArray.removeAll()
    
    let r1 = Int.random(in: 1...6)
    let r2 = Int.random(in: 1...6)
    let r3 = Int.random(in: 1...6)
    let r4 = Int.random(in: 1...6)
    let r5 = Int.random(in: 1...6)
    let r6 = Int.random(in: 1...6)
    let r7 = Int.random(in: 1...6)
    let r8 = Int.random(in: 1...6)
    let r9 = Int.random(in: 1...6)
    
    wisArray.append(r1 + r2 + r3)
    wisArray.append(r4 + r5 + r6)
    wisArray.append(r7 + r8 + r9)
    
    wisStat = wisArray.max()!
    
}

func rollCha() {
    
    chaArray.removeAll()
    
    let r1 = Int.random(in: 1...6)
    let r2 = Int.random(in: 1...6)
    let r3 = Int.random(in: 1...6)
    let r4 = Int.random(in: 1...6)
    let r5 = Int.random(in: 1...6)
    let r6 = Int.random(in: 1...6)
    let r7 = Int.random(in: 1...6)
    let r8 = Int.random(in: 1...6)
    let r9 = Int.random(in: 1...6)
    
    chaArray.append(r1 + r2 + r3)
    chaArray.append(r4 + r5 + r6)
    chaArray.append(r7 + r8 + r9)
    
    chaStat = chaArray.max()!
    
}

func rollStat(arrayNumber: Int, statNumber: Int) {
    
    var allArrays = [strArray, dexArray, consArray, intArray, wisArray, chaArray]
    var allStats = [strStat, dexStat, consStat, intStat, wisStat, chaStat]
    

    allArrays[arrayNumber].removeAll()
    
    let r1 = Int.random(in: 1...6)
    let r2 = Int.random(in: 1...6)
    let r3 = Int.random(in: 1...6)
    let r4 = Int.random(in: 1...6)
    let r5 = Int.random(in: 1...6)
    let r6 = Int.random(in: 1...6)
    let r7 = Int.random(in: 1...6)
    let r8 = Int.random(in: 1...6)
    let r9 = Int.random(in: 1...6)

    allArrays[arrayNumber].append(r1 + r2 + r3)
    allArrays[arrayNumber].append(r4 + r5 + r6)
    allArrays[arrayNumber].append(r7 + r8 + r9)
    
    allStats[statNumber] = allArrays[arrayNumber].max()!

}

// MARK: BODY

var body: some View {

// MARK: STATS UI
    
VStack {
    HStack(spacing: 10) {
            
            VStack(spacing: 6) {
                sixDiceView()
                sixDiceView()
                sixDiceView()
                sixDiceView()
                sixDiceView()
                sixDiceView()
            } //: Vstack
            statNames()
            
            ZStack {
                VStack(spacing: 16)  {
                    Text(String(strStat))
                    Text(String(dexStat))
                    Text(String(consStat))
                    Text(String(intStat))
                    Text(String(wisStat))
                    Text(String(chaStat))
                }
                VStack(spacing: 6)  {
                    Capsule()
                        .fill(Color.blue.opacity(0.2))
                        .frame(width: 60, height: 30)
                    Capsule()
                        .fill(Color.blue.opacity(0.2))
                        .frame(width: 60, height: 30)
                    Capsule()
                        .fill(Color.blue.opacity(0.2))
                        .frame(width: 60, height: 30)
                    Capsule()
                        .fill(Color.blue.opacity(0.2))
                        .frame(width: 60, height: 30)
                    Capsule()
                        .fill(Color.blue.opacity(0.2))
                        .frame(width: 60, height: 30)
                    Capsule()
                        .fill(Color.blue.opacity(0.2))
                        .frame(width: 60, height: 30)
                    
                } //: VStack
            } //: ZStack
            
        ZStack {
            rollsCapsule()
            VStack(alignment: .leading, spacing: 16) {
                Text(\"\\(strArray[0]),\\(strArray[1]),\\(strArray[2])\")
                Text(\"\\(dexArray[0]),\\(dexArray[1]),\\(dexArray[2])\")
                Text(\"\\(consArray[0]),\\(consArray[1]),\\(consArray[2])\")
                Text(\"\\(intArray[0]),\\(intArray[1]),\\(intArray[2])\")
                Text(\"\\(wisArray[0]),\\(wisArray[1]),\\(wisArray[2])\")
                Text(\"\\(chaArray[0]),\\(chaArray[1]),\\(chaArray[2])\")
            } //: VStack
        } //: ZStack
            
    } //: HStack
        
// MARK: BUTTON ROLL
    Button(action:  {
        
        rollStr()
        rollDex()
        rollCons()
        rollInt()
        rollWis()
        rollCha()
        
        })  {
            rollButton()
        } //: BUTTON
  
    } //: VStack
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

}

    标签: swiftui


    【解决方案1】:

    Swift 函数可以使用一个元组返回多个值。如果您创建一个通用滚动函数来返回数组和最大值,您可以调用它并将结果分配给您的变量:

    func roll() -> (array: [Int], max: Int) {
        var result = [Int]()
        
        for _ in 1...3 {
            var sum = 0
            for _ in 1...3 {
                sum += Int.random(in: 1...6)
            }
            result.append(sum)
        }
    
        return (result, result.max()!)
    }
    

    然后你会这样称呼它:

    (strArray, strStat) = roll()
    (dexArray, dexStat) = roll()
        
    

    定义一个RollData 结构

    您的数组和 stat 不应该是两个不同的 @State 变量,因为它们是相关的。您应该将它们组合成一个struct

    struct RollData {
        let array: [Int]
        let stat: Int
    }
    
    func roll() -> RollData {
        var result = [Int]()
        
        for _ in 1...3 {
            var sum = 0
            for _ in 1...3 {
                sum += Int.random(in: 1...6)
            }
            result.append(sum)
        }
        
        return RollData(array: result, stat: result.max()!)
    }
    

    然后你会像这样声明你的 @State 变量:

    @State private var strRoll = roll()
    @State private var dexRoll = roll()
    

    像这样滚动:

    strRoll = roll()
    dexRoll = roll()
    

    并像这样访问数据:

    Text(String(strRoll.stat))
    
    Text("\(strRoll.array[0]),\(strRoll.array[1]),\(strRoll.array[2])")
    

    完整示例

    这是一个有趣的项目。我做了一些额外的更改,我认为您可能希望看到这些更改。

    笔记:

    1. 我创建了一个DieType enum,它对每种模具类型都有一个值。我将其设为Int 类型,以便我们可以将其用作所有模具数组的索引。我将其设为CaseIterable,以便我们可以使用DieType.allCases 获得所有类型的数组。我将其设为CustomStringConvertible,因此该类型可以很好地打印其名称,如计算属性description。我把它做成了Identifiable,这样我们就可以像这样使用它SwiftUI:ForEach(DieType.allCases) { die in
    2. 我创建了一个AllDice struct 来存放所有的骰子。现在我们只需要一个@State dice = AllDice() 来使用该应用程序。它具有滚动所有骰子、按类型滚动单个骰子、获取骰子的statarray 的属性。
    3. 应用程序的主循环是VStack,每个模具类型都有一行。模具类型的数量没有硬编码的 6。通过定义新的模具类型或删除一个,代码会自动适应。
      import SwiftUI
      
      struct RollData {
          let array: [Int]
          let stat: Int
      }
      
      func roll() -> RollData {
          var result = [Int]()
          
          for _ in 1...3 {
              var sum = 0
              for _ in 1...3 {
                  sum += Int.random(in: 1...6)
              }
              result.append(sum)
          }
          
          return RollData(array: result, stat: result.max()!)
      }
      
      enum DieType: Int, CaseIterable, CustomStringConvertible, Identifiable {
          case strength = 0, dexterity, constitution, intelligence, wisdom, charisma
          
          var id: Int { self.rawValue }
          
          var description: String {
              switch self {
              case .strength: return "Strength"
              case .dexterity: return "Dexterity"
              case .constitution: return "Constitution"
              case .intelligence: return "Intelligence"
              case .wisdom: return "Wisdom"
              case .charisma: return "Charisma"
              }
          }
      }
      
      struct AllDice {
          private var dice: [RollData] = (0..<DieType.allCases.count).map { _ in roll() }
          
          func array(die: DieType) -> [Int] {
              dice[die.rawValue].array
          }
          
          func stat(die: DieType) -> Int {
              dice[die.rawValue].stat
          }
          
          mutating func rollDie(die: DieType) {
              dice[die.rawValue] = roll()
          }
          
          mutating func rollAll() {
              for die in DieType.allCases {
                  rollDie(die: die)
              }
          }
      }
      
      struct ContentView: View {
          
          @State private var dice = AllDice()
          
          var body: some View {
              
              // MARK: STATS UI
              
              VStack {
                  ForEach(DieType.allCases) { die in
                      let array = dice.array(die: die)
                      
                      HStack(spacing: 10) {
                          
                          Capsule()
                              .fill(Color.blue.opacity(0.2))
                              .frame(width: 80, height: 30)
                              .overlay (
                                  HStack {
                                      Text("3 x")
                                      Image(systemName: "dice")
                                          .foregroundColor(.red)
                                  }
                              )
                          
                          Text(String(describing: die))
                              .frame(width: 100)
                          
                          Capsule()
                              .fill(Color.blue.opacity(0.2))
                              .frame(width: 50, height: 30)
                              .overlay (
                                  Text(String(describing: dice.stat(die: die)))
      
                              )
                          
                          Capsule()
                              .fill(Color.blue.opacity(0.2))
                              .frame(width: 100, height: 30)
                              .overlay (
                                  Text("\(array[0]), \(array[1]), \(array[2])")
                              )
                      } //: HStack
                      
                  } //: ForEach
                  
                  // MARK: BUTTON ROLL
                  Button(action:  {
                      
                      dice.rollAll()
                      
                  })  {
                      Capsule()
                          .fill(Color.blue.opacity(0.2))
                          .frame(width: 130, height: 30)
                          .overlay (
                              HStack {
                                  Image(systemName: "dice")
                                  Text("Roll Stats")
                              }
                              .foregroundColor(.red)
                          )
                              
                  } //: BUTTON
                  
              } //: VStack
          }
      }
      

    【讨论】:

      猜你喜欢
      • 2017-12-20
      • 1970-01-01
      • 1970-01-01
      • 2014-07-25
      • 2020-11-10
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 2017-01-06
      相关资源
      最近更新 更多