본문 바로가기
언어/Kotlin

[Kotlin 문법 종합] 스레드 활용 실습 (@ 수정하기)

by 젼젼39 2024. 3. 8.

 

1. getInstance() : --> 싱글톤...

import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.util.Random
import kotlin.concurrent.thread

class CashShop private constructor() {
    private val bowPrice = 150
    private val staffPrice = 120

    companion object { 		//object로 되어있음 -> 2마리 동시에 달리고, 1등한 말을 공유해야함. 별도관리x
                            //1등한 말이 없을 때만 달리고, 있으면 달리지 않아야하고, 이름 알아야함
        @Volatile private var instance: CashShop? = null
        @Volatile private var lottoStatus: String? = null 		//1등한 말의 이름 저장
        @Volatile private var isFinish: Boolean? = null 		//1등한 말이 나왔는지, 경주 끝났는지

        fun getInstance(): CashShop {
            // 외부에서 요청왔을때 instance가 null인지 검증
            if(instance == null) {
                // synchronized로 외부 쓰레드의 접근을 막음
                // 쓰레드는 다음챕터에서 소개합니다!
                // 쓰레드간의 객체상태 혼돈을 막기위해 사용한다고 이해해주세요
                synchronized(this) {
                    instance = CashShop()
                }
            }
            return instance!!
        }
    }

2)

    fun purchaseWeapon(character:Character){
        if(character is Archer) {
            character?.run {
                if(money >= bowPrice) {
                    println("[구매 후 금액]: [${money} - ${bowPrice}] = ${money-bowPrice}")
                    money -= bowPrice
                    weapons.add("슈퍼 활")
                } else {
                    println("돈이 부족합니다.")
                }
            }
        } else if(character is Wizard) {
            character?.run {
                if(money >= staffPrice) {
                    println("[구매 후 금액]: [${money} - ${staffPrice}] = ${money-staffPrice}")
                    money -= staffPrice
                    weapons.add("슈퍼 스태프")
                } else {
                    println("돈이 부족합니다.")
                }
            }
        }
    }

3) 로또 부분 : 총 2마리의 말이 달리게 함, 1등한 경우에만 상금을 받

fun startLotto(character: Character, selectHorse: String) { 	//법산지 궁순지, 선택한 말 이름
        var random = Random() 		//랜덤 클래스 사용
        val finalDst = 100 		//최대 100m까지 달리게 설정
        isFinish = false
        thread(start = true) { 		// 말 1마리
            var currentPosition = 0 		//현재 위치 		//밑 코드 : currentPosition이 100m인지, 
            while(currentPosition < finalDst && isFinish == false) { 		// 1등이 나왔는지. 그럼 탈출
                currentPosition += (random.nextInt(5) + 1) 		//0~4(+1로 1~5)랜덤으로 뽑은 값을 계속 더함

                println("1번말 현재 위치: ${currentPosition}m")
                runBlocking {
                    launch {
                        delay(1000)
                    }
                }
            } 	//말이 다 뛰고 난 뒤. lottoStatus null이거나 two가 아니라면 아직 1등말 자리 비어있는거
            if(lottoStatus == null || lottoStatus != "two") { 		
                lottoStatus = "one" 	//얘를 1등으로 지정
                isFinish = true 	//시합 끝남
                println("1등: ${lottoStatus}말")

                if(lottoStatus.equals(selectHorse)) { 		//이 말의 이름이 처음에 고른 말과 같은지
                    println("축하합니다! 당첨!")
                    println("상금으로 1만원 지급")

                    // 왜 이렇게밖에 작성했는지 이유를 생각하고
                    // 코드를 개선하기 ???@@@@@@@@@@@@ 왜지 
                    if(character is Archer) {
                        character?.run {
                            money += 10000
                        }
                    } else if(character is Wizard) {
                        character?.run {
                            money += 10000
                        }
                    }
                }
            }

        }

        thread(start = true) { 		// 말 1마리
            var currentPosition = 0
            while(currentPosition < finalDst && isFinish == false) {
                currentPosition += (random.nextInt(10) + 1)

                println("2번말 현재 위치: ${currentPosition}m")
                runBlocking {
                    launch {
                        delay(1000)
                    }
                }
            }
            if(lottoStatus == null || lottoStatus != "one") {
                lottoStatus = "two"
                isFinish = true
                println("1등: ${lottoStatus}말")
                if(lottoStatus.equals(selectHorse)) {
                    println("축하합니다! 당첨!")
                    println("상금으로 1만원 지급")

                    // 왜 이렇게밖에 작성했는지 이유를 생각하고
                    // 코드를 개선하기
                    if(character is Archer) {
                        character?.run {
                            money += 10000
                        }
                    } else if(character is Wizard) {
                        character?.run {
                            money += 10000
                        }
                    }
                }
            }

        }
    }
}

 

4) WorldMain

4 -> {
    var selectHorse = inputMyInfo("selectHorse").toString()
    startLotto(myCharacter, selectHorse)
   }

5) 

fun startLotto(character: Character, horse: String) {
    var cashShop = CashShop.getInstance()

    cashShop.startLotto(character, horse)
}

 

 

 

++ 더 추가하기...