-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Данила Беляков
authored and
Данила Беляков
committed
Aug 4, 2024
1 parent
95e58f8
commit fda6514
Showing
5 changed files
with
1,281 additions
and
0 deletions.
There are no files selected for viewing
64 changes: 64 additions & 0 deletions
64
examples/src/main/kotlin/com/github/examples/cities/CitiesGameSkill.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package com.github.examples.cities | ||
|
||
import com.github.alice.ktx.dispatch | ||
import com.github.alice.ktx.handlers.message | ||
import com.github.alice.ktx.middleware.outerMiddleware | ||
import com.github.alice.ktx.models.response.response | ||
import com.github.alice.ktx.server.impl.ktorWebServer | ||
import com.github.alice.ktx.skill | ||
import com.github.examples.cities.data.CitiesGameService | ||
|
||
private enum class RegisterUserState { | ||
INPUT_FIST_NAME | ||
} | ||
|
||
fun main() { | ||
|
||
val citiesGameService = CitiesGameService() | ||
|
||
skill { | ||
id = "..." | ||
webServer = ktorWebServer { | ||
port = 8080 | ||
path = "/alice" | ||
} | ||
dispatch { | ||
|
||
outerMiddleware { | ||
if(message.session.user == null) { | ||
return@outerMiddleware response { | ||
text = "У вас нет аккаунта в Яндексе." | ||
} | ||
} | ||
null | ||
} | ||
|
||
message({ message.session.new }) { | ||
val userId = message.session.user!!.userId | ||
val isUserExisting = citiesGameService.isUserExisting(userId) | ||
if(!isUserExisting) { | ||
state.setState(RegisterUserState.INPUT_FIST_NAME.name) | ||
response { text = "Как тебя зовут?" } | ||
}else { | ||
response { text = citiesGameService.startGame(userId).name } | ||
} | ||
} | ||
|
||
message({ state == RegisterUserState.INPUT_FIST_NAME.name }) { | ||
val userId = message.session.user!!.userId | ||
val firstName = message.request.originalUtterance!! | ||
citiesGameService.createUser(id = userId, firstName = firstName) | ||
state.clear() | ||
response { text = citiesGameService.startGame(userId).name } | ||
} | ||
|
||
message { | ||
val userId = message.session.user!!.userId | ||
val cityName = message.request.command!! | ||
response { | ||
text = citiesGameService.processUserAnswer(userId, cityName) | ||
} | ||
} | ||
} | ||
}.run() | ||
} |
85 changes: 85 additions & 0 deletions
85
examples/src/main/kotlin/com/github/examples/cities/data/CitiesGameService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package com.github.examples.cities.data | ||
|
||
import com.github.examples.cities.data.models.City | ||
import com.github.examples.cities.data.models.User | ||
import java.io.File | ||
|
||
class CitiesGameService { | ||
|
||
private val users = mutableMapOf<String, User>() | ||
private val currentCityForUser = mutableMapOf<String, City>() | ||
private val unusedCitiesForUser = mutableMapOf<String, MutableList<City>>() | ||
private val allCities = mutableListOf<City>() | ||
|
||
init { | ||
/** | ||
* Cities [Source](https://github.com/queenofpigeons/SQL_lab/blob/main/Список%20городов%20России.txt) | ||
* */ | ||
val citiesFile = File("examples/src/main/resources/cities.txt") | ||
citiesFile.readLines().forEach { line -> | ||
val city = City(name = line) | ||
allCities.add(city) | ||
} | ||
} | ||
|
||
fun isUserExisting(id: String): Boolean { | ||
return users.containsKey(id) | ||
} | ||
|
||
fun createUser(id: String, firstName: String) { | ||
val user = User(id = id, firstName = firstName) | ||
users[id] = user | ||
} | ||
|
||
fun startGame(userId: String): City { | ||
val city = allCities.random() | ||
currentCityForUser[userId] = city | ||
|
||
val unusedCities = mutableListOf<City>().apply { | ||
addAll(allCities) | ||
remove(city) | ||
} | ||
unusedCitiesForUser[userId] = unusedCities | ||
|
||
return city | ||
} | ||
|
||
fun processUserAnswer(userId: String, cityName: String): String { | ||
val city = allCities.firstOrNull { it.name.equals(cityName.trim(), ignoreCase = true) } | ||
if (city == null) return "Я не знаю такого города." | ||
|
||
val currentCity = currentCityForUser[userId]!! | ||
val lastChar = getEffectiveLastChar(currentCity.name) | ||
val unusedCities = unusedCitiesForUser[userId]!! | ||
|
||
return when { | ||
!unusedCities.contains(city) -> "Такой город уже был." | ||
cityName.first().lowercaseChar() != lastChar -> "Город должен начинаться на букву '$lastChar'." | ||
else -> generateNextCity(userId, city) | ||
} | ||
} | ||
|
||
private fun generateNextCity(userId: String, city: City): String { | ||
val unusedCities = unusedCitiesForUser[userId]!! | ||
unusedCities.remove(city) | ||
|
||
val lastChar = getEffectiveLastChar(city.name) | ||
val nextCity = unusedCities.firstOrNull { it.name.first().lowercaseChar() == lastChar } | ||
|
||
return if (nextCity == null) { | ||
"Поздравляю, вы победили! Начинаем заново: ${startGame(userId).name}." | ||
} else { | ||
unusedCities.remove(nextCity) | ||
currentCityForUser[userId] = nextCity | ||
nextCity.name | ||
} | ||
} | ||
|
||
private fun getEffectiveLastChar(cityName: String): Char { | ||
val trimmedName = cityName.trim().lowercase() | ||
return when (val lastChar = trimmedName.last()) { | ||
'ь', 'ъ', 'ы', 'й' -> trimmedName[trimmedName.length - 2] | ||
else -> lastChar | ||
} | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
examples/src/main/kotlin/com/github/examples/cities/data/models/City.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package com.github.examples.cities.data.models | ||
|
||
data class City( | ||
val name: String | ||
) |
6 changes: 6 additions & 0 deletions
6
examples/src/main/kotlin/com/github/examples/cities/data/models/User.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.github.examples.cities.data.models | ||
|
||
data class User( | ||
val id: String, | ||
val firstName: String | ||
) |
Oops, something went wrong.