【问题标题】:nested for-loops on an array数组上的嵌套 for 循环
【发布时间】:2017-01-13 12:59:30
【问题描述】:

我正在使用SpriteKitSwift 3 创建一个简单的游戏。 我有一组环/圆:

mRings = [mRingOne, mRingTwo, mRingThree, mRingFour, mRingFive]

数组中的每个对象都有不同的颜色,在游戏中的某个时刻我想改变每个环的颜色,但我有两个条件发生这种情况: 1. 戒指不应该具有之前迭代过的颜色。 2. 每个戒指的颜色应该与其他戒指不同。

对于第一个条件,我这样做了:

func changeRingsColor(){
    var previousColor: UIColor?
    for ring in mRings {
        previousColor = ring.fillColor
        repeat{
            ring.fillColor = hexStringToUIColor(hex: mColors[Int(arc4random_uniform(UInt32(5)))])
        }while(ring.fillColor.isEqual(previousColor))
    }
}

它正在工作,但是,我无法找到回答第二个条件的方法。 在Java 我可能会做这样的事情:

    for (int i=0; i<mRings.length; i++){
      for( int j=1; j<mRings.length; j++){
        if (ring[i].fillColor == ring[j].fillColor){
            generate another color for 'j' ring.
        }
    }
 }

但我尝试过的没有任何效果。 希望大家能帮帮我,先谢谢了!

顺便说一句,mColors 是一个包含 5 种不同颜色的数组,我从那里挑选颜色。

【问题讨论】:

  • 您可能正在寻找的是“随机混乱”,即改变每个元素的随机排列。
  • 最简单的算法是生成元素的随机顺序,然后按该顺序将颜色传递给下一个元素。

标签: arrays swift sprite-kit


【解决方案1】:

我将忽略一些实现细节,专注于问题的核心,即:

  • 遍历数组
  • 在每个循环中,从当前索引处开始一个新循环,直到数组末尾。

如果我对上述内容有误解,请告诉我。但我会这样做:

for (index, ring) in mRings.enumerated() {
    let remainingRings = mRings[index+1..<mRings.count]
    for otherRing in remainingRings {
        print("Now comparing \(ring) to \(otherRing)")
    }
}

首先,enumerated() 在第一个 for 循环的每次迭代中为您提供当前环和索引。然后,我们将数组从当前索引切到末尾 (remainingRings),然后循环遍历这些索引。

【讨论】:

  • 不应该是let remainingRings = mRings[index+1..&lt;mRings.count]吗??
【解决方案2】:

用这种方式重写Java代码是可能的:

let mRings = ["mRingOne", "mRingTwo", "mRingThree", "mRingFour", "mRingFive"]

for (index, item) in mRings.enumerated() {
    for item in index + 1..<mRings.count {

    }
}

【讨论】:

    【解决方案3】:

    这样的事情会起作用:

    func changeRingsColor(){
        // extract the previous colors
        let colors = rings.map { $0.fillColor }
        // the order in which the rings will pass color to each other
        let passOrder = mRings.indices.shuffled()
    
        for i in mRings.indices {
            let previous = i == 0 ? mRings.count - 1 : i - 1        
            mRings[passOrder[i]].fillColor = colors[passOrder[previous]]
        }
    }
    

    使用this实现shuffled

    它是如何工作的?

    我不是为每个单独的戒指随机选择颜色,而是随机生成一个顺序,其中戒指将交换颜色 (passOrder)。由于每个戒指都会按顺序将其颜色传递给不同的戒指,因此您可以确定没有颜色会保持不变。

    【讨论】:

    • 这是一种有趣的方法来获得随机“混乱”(没有固定点的排列)。但是,它不会产生所有可能的混乱。例如,ABCD 永远不会被置换为 BADC。 (没有批评,只是评论。)
    • @MartinR 非常正确,对于 4 个项目,恰好错过了 1 个排列:) 我想说明这一点,即不应该对每个元素单独执行算法。
    • 所有超过一个循环的排列都丢失了,除非我弄错了,否则应该是 BADC、CDAB、DCBA 的 4 个项目。 – 但这现在离题了:)
    • @MartinR 哦,是的,我忘记了如果最后一项不是身份,则循环也可以包含 3 项。如果这个算法没有删除太多选项,我将不得不计算。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-18
    • 2020-03-25
    • 2021-10-23
    • 2021-09-03
    • 2017-09-03
    • 2021-09-15
    • 2015-01-09
    相关资源
    最近更新 更多