프로그래밍 심화 주차(Kotlin)
숫자 자료형끼리는 to자료형() 메소드를 활용할 수 있다
문자열을 숫자로 변경할때에는 별도의 메소드가 필요하다
var num1 = 20
var num2 = 30.2
var num3 = num2.toInt()
var num4 = num1.toDouble()
var strNum5 = "10"
var strNum6 = "10.21"
var num5 = Integer.parseInt(strNum5)
var num6 = strNum6.toDouble()
println("num3: $num3")
println("num4: $num4")
println("num5: $num5")
println("num6: $num6")
fun main() {
println("몇 마리를 생성하시겠습니까?")
var count = readLine()!!.toInt()
var birds = mutableListOf()
for(idx in 0..count-1) {
println("조류의 이름을 입력해주세요")
var name = readLine()!!
// as Bird는 생략가능
birds.add(Sparrow(name) as Bird)
}
println("============조류 생성완료============")
for(bird in birds) {
bird.fly()
}
}
open class Bird(name: String) {
var name: String
init {
this.name = name
}
fun fly() {
println("${name}이름의 조류가 날아요~")
}
}
class Sparrow(name: String): Bird(name) {
}
fun main() {
println("몇 마리를 생성하시겠습니까?")
var count = readLine()!!.toInt()
var birds = mutableListOf()
for(idx in 0..count-1) {
println("조류의 이름을 입력해주세요")
var name = readLine()!!
birds.add(Sparrow(name) as Bird)
}
println("============조류 생성완료============")
for(bird in birds) {
bird.fly()
}
// 다운캐스팅 오류
// Sparrow는 Bird가 가져야할 정보를 모두 가지고 있지 않기 때문임
// var s1:Sparrow = birds.get(0)
}
open class Bird(name: String) {
var name: String
init {
this.name = name
}
fun fly() {
println("${name}이름의 조류가 날아요~")
}
}
class Sparrow(name: String): Bird(name) {
}
if(name is String) {
println("name은 String 타입입니다")
} else {
println("name은 String 타입이 아닙니다")
}
var chicken = Chicken()
var eggs = chicken.getEggs()
var listEggs = eggs.toList()
// first, second로 관리
// var firstEgg = eggs.first
// var secondEgg = eggs.second
// 리스트로 관리
var firstEgg = listEggs[0]
var secondEgg = listEggs[1]
println("달걀의 종류는 ${eggs} 입니다.")
println("리스트 달걀의 종류는 ${listEggs} 입니다.")
println("첫번째 달걀의 종류는 ${firstEgg} 입니다.")
println("두번째 달걀의 종류는 ${secondEgg} 입니다.")
}
class Chicken {
fun getEggs(): Pair<String, String> {
var eggs = Pair("달걀", "맥반석")
return eggs
}
}
fun main() {
var chicken = Chicken()
var eggs = chicken.getThreeEggs()
var listEggs = eggs.toList()
// first, second, third로 관리
// var firstEgg = eggs.first
// var secondEgg = eggs.second
// var eggTime = eggs.third
// 리스트로 관리
var firstEgg = listEggs[0]
var secondEgg = listEggs[1]
var eggTime = listEggs[2]
println("달걀의 정보는 ${eggs} 입니다.")
println("리스트 달걀의 정보는 ${listEggs} 입니다.")
println("첫번째 달걀의 종류는 ${firstEgg} 입니다.")
println("두번째 달걀의 종류는 ${secondEgg} 입니다.")
println("달걀은 ${eggTime}에 나왔습니다.")
}
class Chicken {
fun getTwoEggs(): Pair<String, String> {
var eggs = Pair("달걀", "맥반석")
return eggs
}
fun getThreeEggs(): Triple<String, String, Int> {
var eggs = Triple("달걀", "맥반석", 20230101)
return eggs
}
}
중괄호 블록안에 it으로 자신의 객체를 전달하고 수행된 결과를 반환한다.
var strNum = "10"
var result = strNum?.let {
// 중괄호 안에서는 it으로 활용함
Integer.parseInt(it)
}
println(result!!+1)
중괄호 블록안에 this로 자신의 객체를 전달하고 코드를 수행한다.
this는 생략해서 사용할 수 있으므로 반드시 null이 아닐때만 사용하는 게 좋다.
var alphabets = "abcd"
with(alphabets) {
// var result = this.subSequence(0,2)
var result = subSequence(0,2)
println(result)
}
fun main() {
var student = Student("참새", 10)
var result = student?.also {
it.age = 50
}
result?.displayInfo()
student.displayInfo()
}
class Student(name: String, age: Int) {
var name: String
var age: Int
init {
this.name = name
this.age = age
}
fun displayInfo() {
println("이름은 ${name} 입니다")
println("나이는 ${age} 입니다")
}
}
fun main() {
var student = Student("참새", 10)
var result = student?.apply {
student.age = 50
}
result?.displayInfo()
student.displayInfo()
}
class Student(name: String, age: Int) {
var name: String
var age: Int
init {
this.name = name
this.age = age
}
fun displayInfo() {
println("이름은 ${name} 입니다")
println("나이는 ${age} 입니다")
}
}
var totalPrice = run {
var computer = 10000
var mouse = 5000
computer+mouse
}
println("총 가격은 ${totalPrice}입니다")
fun main() {
var student = Student("참새", 10)
student?.run {
displayInfo()
}
}
class Student(name: String, age: Int) {
var name: String
var age: Int
init {
this.name = name
this.age = age
}
fun displayInfo() {
println("이름은 ${name} 입니다")
println("나이는 ${age} 입니다")
}
}
fun main() {
var student = Student("참새", 10)
student?.run {
displayInfo()
}
}
class Student(name: String, age: Int) {
var name: String
var age: Int
init {
this.name = name
this.age = age
}
fun displayInfo() {
println("이름은 ${name} 입니다")
println("나이는 ${age} 입니다")
}
}
// Scope Function을 중첩으로 사용할 경우 누가 누구의 범위인지 알수 없다!
// Implicit parameter 'it' of enclosing lambda is shadowed 경고 발생!
data class Person(
var name: String = "",
var age: Int? = null,
var child: Person? = null
)
// 잘못된 예시
Person().also {
it.name = "한석봉"
it.age = 40
val child = Person().also {
it.name = "홍길동" // 누구의 it인지 모른다!
it.age = 10 // 누구의 it인지 모른다!
}
it.child = child
}
// 수정한 예시
Person().also {
it.name = "한석봉"
it.age = 40
val child = Person().also { c ->
c.name = "홍길동"
c.age = 10
}
it.child = child
}
fun main() {
fun Student.getGrade() = println("학생의 등급은 ${this.grade} 입니다")
var student = Student("참새", 10, "A+")
student.displayInfo()
student.getGrade()
}
class Student(name: String, age: Int, grade: String) {
var name: String
var age: Int
var grade: String
init {
this.name = name
this.age = age
this.grade = grade
}
fun displayInfo() {
println("이름은 ${name} 입니다")
println("나이는 ${age} 입니다")
}
}
// CashShop.kt
class CashShop private constructor() {
private val bowPrice = 150
private val staffPrice = 120
companion object {
@Volatile private var instance: CashShop? = null
fun getInstance(): CashShop {
// 외부에서 요청왔을때 instance가 null인지 검증
if(instance == null) {
// synchronized로 외부 쓰레드의 접근을 막음
// 쓰레드는 다음챕터에서 소개합니다!
// 쓰레드간의 객체상태 혼돈을 막기위해 사용한다고 이해해주세요
synchronized(this) {
instance = CashShop()
}
}
return instance!!
}
}
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("돈이 부족합니다.")
}
}
}
}
}
// WorldMain.kt
fun main() {
val worldName = "스코월드"
var myName = inputMyInfo("name").toString()
var myAge = inputMyInfo("age").toString().toInt()
var myJob = inputMyInfo("job").toString()
var myGender = inputMyInfo("gender").toString()
var myMoney = inputMyInfo("money").toString().toInt()
var myHp = inputMyInfo("hp").toString().toInt()
var isNamePass = true
var isAgePass = true
var isJobPass = true
var names = mutableListOf("참새", "꿩", "비둘기")
for(name in names) {
if(myName == name) {
println("중복된 이름이 존재합니다.")
isNamePass = false
break
}
}
if(myAge < 12) {
println("12세 미만은 이용할 수 없습니다.")
isAgePass = false
}
if(myJob == "전사") {
println("일시적으로 전사를 이용할 수 없습니다.")
isJobPass = false
}
// 모든 조건을 통과한 경우에만 환영
if(isNamePass && isAgePass && isJobPass) {
// 새로 이름 추가
names.add(myName)
displayInfo(worldName, myName, myAge, myJob)
if(myJob == "마법사") {
println("마법사는 초기 mp도 입력해주세요")
var myMp = inputMyInfo("mp").toString().toInt()
var myCharacter = Wizard(myName, myAge, myGender, myMoney, myHp, myMp)
while(true) {
println("[1] 슬라임동굴, [2] 좀비마을, [3] 캐쉬샵, [4] 종료")
var selectNumber= inputMyInfo("selectNumber").toString().toInt()
when(selectNumber) {
1 -> {
selectWorld(1, myCharacter)
}
2 -> {
selectWorld(2, myCharacter)
}
3 -> {
openCashShop(myCharacter)
}
4 -> {
println("게임 종료")
break
}
else -> {
break
}
}
}
} else if(myJob == "궁수") {
println("궁수를 선택했군요")
var myCharacter = Archer(myName, myAge, myGender, myMoney, myHp)
while(true) {
println("[1] 슬라임동굴, [2] 좀비마을, [3] 캐쉬샵, [4] 종료")
var selectNumber= inputMyInfo("selectNumber").toString().toInt()
when(selectNumber) {
1 -> {
selectWorld(1, myCharacter)
}
2 -> {
selectWorld(2, myCharacter)
}
3 -> {
openCashShop(myCharacter)
}
4 -> {
println("게임 종료")
break
}
else -> {
break
}
}
}
}
}
}
fun displayInfo(worldName:String, myName:String, myAge:Int, myJob:String) {
println("==================${worldName}에 오신것을 환영합니다==================")
println("당신의 정보는 다음과 같습니다.")
println("이름: ${myName}입니다.")
println("나이: ${myAge}입니다.")
println("직업: ${myJob}입니다.")
println("모험을 떠나 볼까요?")
}
fun selectWorld(selectWorld:Int, myCharacter: Character) {
if(selectWorld == 1) { // 슬라임 던전
if(myCharacter is Archer) {
var slime1 = Slime("초록슬라임", "초록", 30.2, 200, 10)
slime1.attack()
myCharacter.windArrow()
slime1.poison()
} else if(myCharacter is Wizard) {
var slime1 = Slime("파랑슬라임", "파랑", 30.2, 200, 10)
slime1.attack()
myCharacter.fireBall()
slime1.poison()
}
} else if(selectWorld == 2) { // 좀비 던전
if(myCharacter is Archer) {
var zombie1 = Zombie("파랑좀비", "파랑", 142.2, 500, 25)
zombie1.virus()
myCharacter.windJump("건물1")
} else if(myCharacter is Wizard) {
var zombie1 = Zombie("파랑좀비", "파랑", 142.2, 500, 25)
zombie1.virus()
myCharacter.teleport(10, 20)
}
}
}
fun inputMyInfo(type:String): Any? {
return when(type) {
"name" -> {
println("이름을 입력해주세요")
while(true) {
try {
var originName = readLine()
if(originName?.first() != '_' && originName?.first() != '!') {
return originName
} else {
println("이름을 다시 입력해주세요")
}
} catch(e:Exception) {
println("이름을 다시 입력해주세요")
}
}
}
"age" -> {
println("나이를 입력해주세요")
while(true) {
try {
var originAge:String? = readLine()
return originAge?.toInt() ?: -1
} catch(e:Exception) {
println("나이를 다시 입력해주세요")
}
}
}
"job" -> {
println("직업을 입력해주세요")
while(true) {
try {
var originName = readLine()
if(originName?.equals("궁수") == true || originName?.equals("마법사") == true) {
return originName
} else {
println("직업을 다시 입력해주세요")
}
} catch(e:Exception) {
println("직업을 다시 입력해주세요")
}
}
}
"gender" -> {
println("성별을 입력해주세요")
while(true) {
try {
var originGender = readLine()
if(originGender?.equals("남") == true || originGender?.equals("여") == true) {
return originGender
} else {
println("성별을 다시 입력해주세요")
}
} catch(e:Exception) {
println("성별을 다시 입력해주세요")
}
}
}
"money" -> {
println("초기자본을 입력해주세요")
while(true) {
try {
var originMoney:String? = readLine()
return originMoney?.toInt() ?: -1
} catch(e:Exception) {
println("초기자본을 다시 입력해주세요")
}
}
}
"hp" -> {
println("초기체력을 입력해주세요")
while(true) {
try {
var originHp:String? = readLine()
return originHp?.toInt() ?: -1
} catch(e:Exception) {
println("초기체력을 다시 입력해주세요")
}
}
}
"mp" -> {
println("초기마나를 입력해주세요")
while(true) {
try {
var originMp:String? = readLine()
return originMp?.toInt() ?: -1
} catch(e:Exception) {
println("초기마나를 다시 입력해주세요")
}
}
}
"selectWorld" -> {
println("월드를 선택해주세요")
while(true) {
try {
var selectWorld:String? = readLine()
return selectWorld?.toInt() ?: -1
} catch(e:Exception) {
println("월드를 다시 선택해주세요")
}
}
}
"selectNumber" -> {
println("번호를 선택해주세요")
while(true) {
try {
var selectNumber:String? = readLine()
return selectNumber?.toInt() ?: -1
} catch(e:Exception) {
println("번호를 다시 선택해주세요")
}
}
}
else -> {
return "no"
}
}
}
fun openCashShop(character: Character) {
var cashShop = CashShop.getInstance()
if(character is Archer) {
println("구매전 무기: ${character.weapons}")
cashShop.purchaseWeapon(character)
println("구매후 무기: ${character.weapons}")
} else if(character is Wizard) {
println("구매전 무기: ${character.weapons}")
cashShop.purchaseWeapon(character)
println("구매후 무기: ${character.weapons}")
}
}
이런 유용한 정보를 나눠주셔서 감사합니다.