新Swiftで行こう…第60回「トランプ2解説」 田部井保
トランプ2の解説です。
まずJKを出すというものでした。
//
// ViewController.swift
// Card
//
// Created by 保 Tabei on 2024/09/25.
//
import UIKit
class ViewController: UIViewController {
///カード表示用ラベル
@IBOutlet weak var lblCard: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
///マーク保持配列
let mark: [String] = ["♣️","♦️","❤️","♠️"]
///ナンバー保持配列
let number: [String] = ["A","2","3","4","5","6","7","8","9","T","J","Q","K"]
///ボタン押下時処理
@IBAction func btnGoTouch(_ sender: Any) {
//カード乱数発生(0〜52)
let card = Int.random(in: 0 ..< 53)
//ジョーカーの場合
if card == 52 {
lblCard.text = "JK"
//ジョーカー以外の場合
} else {
//カード表示用ラベルにマークとナンバーを表示
lblCard.text = mark[card / 13] + number[card % 13]
}
}
}
27行目で、ジョーカーの分、枚数を1枚増やして、53枚としています。
29行目で、card が52か調べ、52ならジョーカーを表示しています。それ以外なら、今まで通り、マークとナンバーを表示しています。マークとナンバーを分けて乱数を発生させていたら、ジョーカーを出すのは難しいですね。
一度使ったカードがもう出ない様にする。
//
// ViewController.swift
// Card
//
// Created by 保 Tabei on 2024/09/25.
//
import UIKit
class ViewController: UIViewController {
///カード表示用ラベル
@IBOutlet weak var lblCard: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
///マーク保持配列
let mark: [String] = ["♣️","♦️","❤️","♠️"]
///ナンバー保持配列
let number: [String] = ["A","2","3","4","5","6","7","8","9","T","J","Q","K"]
///既に出ているかチェックする、出ていたらtrue
///出ていなかったらfalse、とりあえず53枚分
///falseで埋める
var check = [Bool](repeating: false, count: 53)
///ボタン押下時処理
@IBAction func btnGoTouch(_ sender: Any) {
//カード番号保持変数
var card:Int
repeat {
//カード乱数発生(0〜52)
card = Int.random(in: 0 ..< 53)
//既に出ていたら繰り返す
} while check[card]
//新たに出たカード既に出ているとマークする
check[card] = true
//ジョーカーの場合
if card == 52 {
lblCard.text = "JK"
//ジョーカー以外の場合
} else {
//カード表示用ラベルにマークとナンバーを表示
lblCard.text = mark[card / 13] + number[card % 13]
}
}
}
27行目で、bool型の配列を定義しています。bool型とは、true か false を取る変数で、if val > randInt の val > randInt の結果も bool型となっています。ここでは53個分、false で初期化しています。check[11] が false なら♣️のQは、まだ出ていない事を示していて、true なら、既に出ている事を示しています。
33行目、37行目の repeat { 〜 } while check[card] は、while 以降がtrueなら繰り返すという構文です。内部で、card 変数に0〜52の乱数を発生させています。ここで、最初 card が11だったら、check 配列は全て false なので while 以降が true になる事が無いので、ループを抜けます。40行目で、check[card] に true を入れています。card が11なので、check[11] が true になります。2度目、ボタンを押したとします。ここで、card が30だったら、❤️の5なのですが、check[30] は、まだ false なので、ループを抜けます。40行目で、 check[30] が true になります。3度目、ボタンを押したとします。ここで、card が51だったら、♠️のKなのですが、check[51] は、まだ false なので、ループを抜けます。40行目で、check[51] が true になります。4度目、ボタンを押したとします。ここで、card が30だったら、check[30] は既に true になっているのでループします。もう一度乱数を発生させて、card が5だったら、♣️の6なのですが、check[5] は、まだ false なので、ループを抜けます。40行目で、check[5] が true になります。この様な動きをします。
定数を使う。
//
// ViewController.swift
// Card
//
// Created by 保 Tabei on 2024/09/25.
//
import UIKit
class ViewController: UIViewController {
///カード表示用ラベル
@IBOutlet weak var lblCard: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
///マーク保持配列
let mark: [String] = ["♣️","♦️","❤️","♠️"]
///ナンバー保持配列
let number: [String] = ["A","2","3","4","5","6","7","8","9","T","J","Q","K"]
///カード枚数保持定数
enum EnumCard {
static let Count = 53
}
///既に出ているかチェックする、出ていたらtrue
///出ていなかったらfalse、とりあえず
///EnumCard.Count枚分falseで埋める
var check = [Bool](repeating: false, count: EnumCard.Count)
///ボタン押下時処理
@IBAction func btnGoTouch(_ sender: Any) {
//カード番号保持変数
var card:Int
repeat {
//カード乱数発生(0〜EnumCard.Count - 1)
card = Int.random(in: 0 ..< EnumCard.Count)
//既に出ていたら繰り返す
} while check[card]
//新たに出たカード既に出ているとマークする
check[card] = true
//ジョーカーの場合
if card == 52 {
lblCard.text = "JK"
//ジョーカー以外の場合
} else {
//カード表示用ラベルにマークとナンバーを表示
lblCard.text = mark[card / 13] + number[card % 13]
}
}
}
Swift では、定数は25行目〜27行目の様に定義する様です。単純にlet 定数を作れば良いと思っていましたが、それですと、32行目でエラーになってしまいます。32行目、40行目の様に適用します。ここで、第12回「トランプ2」では、48行目も EnumCard.Count – 1 としていたのですが、よく考えてみたらジョーカーは52にしておかないと、まずかったです。♣️のKとかが、ジョーカーになってしまいます。