【iOS】#26 Set(神奇形色牌) Part1: 遊戲規則設定、svg 控制

製作一個 Set 遊戲 App

--

前陣子 Peter 跟我說到這款遊戲,是史丹佛大學 Swift 課程的期末作業。實際下載其他人製作的 Set game,玩了一下後發現蠻燒腦的,決定自己也來做。

Set 卡牌樣貌

遊戲規則

先來了解一下 Set 的遊戲規則,這原本是一款卡牌遊戲,遊戲的規則就是從一堆卡牌中,找到可以組成 “Set” 的牌組。總而言之就是一種找牌組的遊戲。

何謂 “Set”

Set 遊戲中會有 81 張牌(四種特徵,每種特徵有三種,所以總共有 3⁴ = 81 種不同卡片),每一張牌的樣式都不一樣。是由以下特徵進行排列組合而成:

  • 形狀:菱形、圓角矩形、S型
  • 顏色:紅色、綠色、藍色
  • 填充樣式:實心、空心、斜線
  • 形狀數量:1–3 個

要組成一個 Set 要有三張牌,並且符合以下規則:

  • 三張特徵都一樣,例如都是菱形
  • 三張特徵都不一樣,例如分別為菱形、圓角矩形、S型

四種特徵都要符合以上特徵,所以其實選定兩張牌時,要組成 Set 的可能性只有一種。看看以下範例:

以上皆為 Set (傳統的 Set 中的S型形狀看起來不太順,所以我就它改成了三角形 XD)

App 構想

玩法的部分,可以有很多種模式變化。市面上的 App 免費版的通常都是限時模式,例如給定 1 分鐘,看可以找出幾組 Set。

不過實際玩起來發現 1 分鐘太短,所以我製作的版本是找10組 Set,並記錄下所花的時間,作為排名。

到遊戲頁面後,隨機給 12 張卡牌

App 架構

用 SetProp struct 記錄卡牌的資訊,包含形狀、數量、填充、顏色:

有關 Set 卡牌的處理,我使用了 SetCardHelper 做統一管理:

  • allCards:所有卡牌 (81張)
  • remainCards:除了場面上的其他牌 (69張)
  • currentCards:場面上的牌 (12張)
  • currentSets:場面上的牌可組為幾個 Set
  • selected:玩家目前選的牌組,key 記錄在 currentCards 中的 index
  • setFoundCount:記錄玩家已經找出幾個 Set

App 實作

判斷是否為 Set

這邊使用泛型的寫法,使用 T 代表某一種型態,並宣告為 Comparable,代表這類型皆遵從 Comparable 協議,可以進行比較

func isSet<T: Comparable>(_ first: T, _ second: T, _ third: T) -> Bool {
if first == second, second == third {
return true
}
if first != second, second != third, third != first {
return true
}
return false
}

根據規則,三卡牌特徵一致 return true;三卡牌特徵不一致 return true,除此之外皆是 false

然後再把選中的卡牌們在 checkSingleSet 中,進行四種特徵的判斷,最後得到這三張是否為 Set

控制 svg 顏色

Set 卡牌總共有 81 張,非常的多,如果要使用圖檔的話,設計師會畫到瘋掉… 所以把顏色、數量交給程式生成比較方便

Xcode 雖然支援 svg 圖片,不過不像網頁開發那樣,容易更換它的填充顏色,所以這邊我使用了 SwiftSVG 這個套件

svgURL,先從 Bundle.main.url 中找到專案中的 svg 檔,接著從 SetProp 中決定要有幾個 UIView 。每個 UIView 的 layer 中再畫形狀,在 layer 的 fillColor 中即可設定顏色

為了達到響應式的設計,所以上述程式碼中,會去計算 layer 的位置,讓它至於 UIView 中央

使用 CollectionView Cell,Cell 由外至內為 UIView -> StackView -> UIView(存形狀,可能不只一個)

Demo

--

--