저번 스톱워치를 만들고 나서 다음에는 어떤 것을 만들어 볼까 생각하다가 현재 진행 중인 개인 프로젝트도 있고 해서 연습 삼아 간단한 게임을 하나 만들어보려고 합니다. 크게 어려움은 없어서 따라 하기 쉽거나 아니면 더욱 쉽게 만드실 수 있을 거라고 생각합니다.
(이런 저런 것을 사용해보면서 감각을 늘려나가신다 생각하시면 될 것 같습니다.)
1. Storyboard에 디자인 작성
자신의 감각을 살려서 간단하게 디자인을 만들어줍니다.
저 같은 경우는 컴퓨터의 출력 값을 나타내는 라벨, 이겼는지 졌는지 혹은 비겼는지를 나타내는 결과 라벨
그리고 자신이 낼 수 있는 가위, 바위, 보 각각의 버튼 그 버튼들을 감싸는 스택 뷰 정도만 사용하였습니다.
(제약은 결과 라벨을 중앙을 기준으로 적당히 설정하였습니다.)
2. Enum설정
굳이 설정 안하셔도 되지만 관리를 쉽게 하기 위해서 두 가지의 enum타입을 설정해주었습니다.
enum ResultState: String { // 컴퓨터의 결과와 대조하여 이겼는지 졌는지를 확인할 때 사용
case win = "win"
case draw = "draw"
case lose = "lose"
}
enum SRPState { // 가위 바위 보의 값
case scissors
case rock
case paper
var num: Int { // 후에 랜덤값에 사용할 데이터
switch self {
case .scissors: return 0
case .rock: return 1
case .paper: return 2
}
}
var message: String {
switch self {
case .scissors: return "scissors"
case .rock: return "rock"
case .paper: return "paper"
}
}
}
3. 유저의 입력값 설정
간단히 컴퓨터의 결괏값과 유저의 입력값을 두 개의 Switch문을 사용하여 구현하였습니다.
여기서 승부 결과의 라벨에 사용되는 문자열은 아까 만든 enum타입을 사용하였습니다.
private func startProcessing(_ input: SRPState) {
guard let computerOutput = (컴퓨터의 결과 값 메소드) else {
print("return value is nil")
return
}
switch input {
case .scissors:
switch computerOutput {
case .scissors: self.resultDescriptionLabel.text = ResultState.draw.rawValue
case .rock: self.resultDescriptionLabel.text = ResultState.lose.rawValue
case .paper: self.resultDescriptionLabel.text = ResultState.win.rawValue
}
case .rock:
switch computerOutput {
case .scissors: self.resultDescriptionLabel.text = ResultState.win.rawValue
case .rock: self.resultDescriptionLabel.text = ResultState.draw.rawValue
case .paper: self.resultDescriptionLabel.text = ResultState.lose.rawValue
}
case .paper:
switch computerOutput {
case .scissors: self.resultDescriptionLabel.text = ResultState.lose.rawValue
case .rock: self.resultDescriptionLabel.text = ResultState.win.rawValue
case .paper: self.resultDescriptionLabel.text = ResultState.draw.rawValue
}
}
}
4. 컴퓨터의 결과 값 만들기
사용되는 것은 랜덤 값뿐이기 때문에 간단히 구현하실 수 있습니다.
(가위 바위 보 세 가지뿐이 없기 때문에 적당히 0에서 2 정도로 랜덤을 돌려주시면 됩니다.)
여기서는 아까 만든 enum타입의 num을 사용하여해 주시면 됩니다.
private func computingState() -> SRPState? {
let computingValue = Int.random(in: 0...2)
switch computingValue {
case SRPState.scissors.num:
self.resultLabel.text = SRPState.scissors.message
return .scissors
case SRPState.rock.num:
self.resultLabel.text = SRPState.rock.message
return .rock
case SRPState.paper.num:
self.resultLabel.text = SRPState.paper.message
return .paper
default:
return nil
}
}
5. 완성 코드
class ViewController: UIViewController {
/// Enum Properties
enum ResultState: String {
case win = "win"
case draw = "draw"
case lose = "lose"
}
enum SRPState {
case scissors
case rock
case paper
var num: Int {
switch self {
case .scissors: return 0
case .rock: return 1
case .paper: return 2
}
}
var message: String {
switch self {
case .scissors: return "scissors"
case .rock: return "rock"
case .paper: return "paper"
}
}
}
/// IBOutlet Properties
@IBOutlet weak var resultLabel: UILabel!
@IBOutlet weak var resultDescriptionLabel: UILabel!
@IBOutlet weak var scissors: UIButton!
@IBOutlet weak var rock: UIButton!
@IBOutlet weak var paper: UIButton!
/// Override Methods
override func viewDidLoad() {
super.viewDidLoad()
}
/// IBAction Methods
@IBAction func didTappedScissors(_ sender: UIButton) {
self.startProcessing(.scissors)
}
@IBAction func didTappedRock(_ sender: UIButton) {
self.startProcessing(.rock)
}
@IBAction func didTappedPaper(_ sender: UIButton) {
self.startProcessing(.paper)
}
}
/// MARK:- Process
extension ViewController {
/// 결과 출력
///
/// Parameters:
/// input - 입력한 데이터 값
private func startProcessing(_ input: SRPState) {
guard let computerOutput = (컴퓨터의 결과 값 메소드) else {
print("return value is nil")
return
}
switch input {
case .scissors:
switch computerOutput {
case .scissors: self.resultDescriptionLabel.text = ResultState.draw.rawValue
case .rock: self.resultDescriptionLabel.text = ResultState.lose.rawValue
case .paper: self.resultDescriptionLabel.text = ResultState.win.rawValue
}
case .rock:
switch computerOutput {
case .scissors: self.resultDescriptionLabel.text = ResultState.win.rawValue
case .rock: self.resultDescriptionLabel.text = ResultState.draw.rawValue
case .paper: self.resultDescriptionLabel.text = ResultState.lose.rawValue
}
case .paper:
switch computerOutput {
case .scissors: self.resultDescriptionLabel.text = ResultState.lose.rawValue
case .rock: self.resultDescriptionLabel.text = ResultState.win.rawValue
case .paper: self.resultDescriptionLabel.text = ResultState.draw.rawValue
}
}
}
/// 컴퓨터의 결과 처리
///
private func computingState() -> SRPState? {
let computingValue = Int.random(in: 0...2)
switch computingValue {
case SRPState.scissors.num:
self.resultLabel.text = SRPState.scissors.message
return .scissors
case SRPState.rock.num:
self.resultLabel.text = SRPState.rock.message
return .rock
case SRPState.paper.num:
self.resultLabel.text = SRPState.paper.message
return .paper
default:
return nil
}
}
한 번 시행해보면 잘 작동하는 것을 확인할 수 있습니다.
다음 글에서는 몇 판 몇 승 시스템과 디자인을 좀 더 꾸며 보겠습니다.
감사합니다.
환경
Xcode 11.3.1
swift 5
'Swift > 데모 개발' 카테고리의 다른 글
[Swift] 아날로그 시계 어플을 만들어보자! (0) | 2020.06.01 |
---|---|
[Swift] 달력 App 만들어보기 (4) | 2020.04.27 |
[Swift] 가위 바위 보 게임 만들기 - Step 2 (0) | 2020.04.05 |
[Swift] StopWatch 만들어보기 - Step 2 (0) | 2020.03.07 |
[Swift] StopWatch 만들어보기 - Step 1 (0) | 2020.03.07 |