-
Notifications
You must be signed in to change notification settings - Fork 206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[๐ 3๋จ๊ณ - ์ง๋ขฐ ์ฐพ๊ธฐ(๊ฒ์ ์คํ)] ์ ์ข ํ ๋ฏธ์ ์ ์ถํฉ๋๋ค. #487
base: jjongwa
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3๋จ๊ณ ๋ฏธ์
๊ณ ์ ๋ง์ผ์
จ์ด์!
์ฌ๋ฌ ์๊ฐํด๋ณผ๋งํ ๊ณณ์ ์ฝ๋ฉํธ ๋จ๊ฒจ๋์์ด์.
ํผ๋๋ฐฑ ๋ฐ์ ํ ๋ค์ ๋ฆฌ๋ทฐ ์์ฒญ ๋ถํ๋๋ ค์!
private fun createField(): Map<Position, Spot> { | ||
val spots = mutableMapOf<Position, Spot>() | ||
for (x in 0 until fieldInfo.getWidth() + 1) { | ||
for (y in 0 until fieldInfo.getHeight() + 1) { | ||
val position = Position(x, y) | ||
spots[position] = | ||
if (minePositions.contains(position)) { | ||
MineSpot(position) | ||
} else { | ||
SafeSpot(position, getNearByMineCount(minePositions, position)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
์ง๋ขฐ์ฐพ๊ธฐ๋ฅผ ์ฒ์ ์์ํ ๋๋ถํฐ ์ฃผ๋ณ ์ง๋ขฐ์ ๊ฐ์๋ฅผ ๋ฃ์ด์ค ์๋ ์๊ฒ ์ง๋ง,
์ด๋ค ์นธ์ ์ด์์ ๋ ๊ณ์ฐํ๋๋ก ๊ตฌํํด๋ณด๋ ๊ฑด ์ด๋จ๊น์?
์์ง ์ด์ง ์์ ์นธ๋ค์ ๋ชจ๋ ๊ณ์ฐํด์ ๋ฏธ๋ฆฌ ๊ฐ์ ๋ฃ์ด๋๋ ๊ฑด ๋ญ๋น์ผ ์๋ ์๊ฒ ๋ค๋ ์๊ฐ์ด ์์ด์ :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ํ๋ ํฌ๊ธฐ๊ฐ ํด์๋ก ๋ถํ์ํ๊ฒ ๋ค์.!
open ์์ ์ ์ฃผ๋ณ ์ง๋ขฐ ๊ฐ์๋ฅผ ๊ณ์ฐํด ์
๋ฐ์ดํธ ํ๋๋ก ๋ณ๊ฒฝํด ์ฃผ์์ต๋๋ค! 19f1404
return NearbyDirection.entries | ||
.toTypedArray() | ||
.count { direction -> | ||
val nearbyPosition = | ||
Position( | ||
position.x + direction.dx(), | ||
position.y + direction.dy(), | ||
) | ||
minePositions.contains(nearbyPosition) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Position ๊ฐ์ฒด์๊ฒ ํด๋น ๊ฐ์ฒด ์ฃผ๋ณ์ Position์ ๋ฌด์์ด ์๋์ง ๋ฉ์์ง๋ฅผ ๋์ ธ ๋ฐํํ๋๋ก ๊ตฌ์ฑํด๋ณด๋ ๊ฑด ์ด๋จ๊น์?
val nearbyPositions = position.nearbyPositions()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
data class Position(val x: Int, val y: Int) {
fun nearbyPositions(): Set<Position> {
return NearbyDirection.entries.map { direction ->
Position(
x + direction.dx(),
y + direction.dy(),
)
}.toSet()
}
}
Position์ด ํด๋น ์ฑ
์์ ๊ฐ์ง๋๋ก ์ด๋ํด ์ฃผ์์ต๋๋ค.
getNearByMineCount์ ๊ตฌ์กฐ๊ฐ ํจ์ฌ ๊น๋ํด์ก๋ค์! ๐
private fun getNearByMineCount(
minePositions: Set<Position>,
position: Position,
): Int {
val nearbyPositions = position.nearbyPositions()
return nearbyPositions.count { it in minePositions }
}
fun openSpot(position: Position) { | ||
val targetSpot = spots[position] as SafeSpot | ||
targetSpot.open() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
์ฌ๋ ์นธ์ ์์น๊ฐ ์ง๋ขฐ์ธ ๊ฒฝ์ฐ๋ ํ์
์บ์คํ
Exception์ด ๋ํ๋ ๊ฒ์ผ๋ก ์ฐ๋ ค๋ผ์.
์ง๋ขฐ์ธ ๊ฒฝ์ฐ์ ๊ฒ์์ด ๋น์ ์ ์ข
๋ฃ๋์ง ์๋๋ก ์ฒ๋ฆฌํด๋ณด๋ ๊ฑด ์ด๋จ๊น์?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
๊ธฐ์กด์ ์ฌ๋ ์นธ์ ์์น๊ฐ Mine์ธ์ง ์ฌ๋ถ๋ฅผ Game์์ ๋ฐ๋ก ํ์ธํ ๋ค openSpot์ ํธ์ถํ๋ ๊ตฌ์กฐ์์ง๋ง,
Mine์ธ์ง ์ฌ๋ถ๋ฅผ openSpot์ ํฌํจ์ํค๋ก ํด๋น ์ฌ๋ถ๋ฅผ Boolean๊ฐ์ผ๋ก ๋ฐ์ ๊ฒ์ ์ข
๋ฃ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ตฌ์กฐ๋ก ๋ณ๊ฒฝํ์ต๋๋ค! 49f3806
fun open() { | ||
require(!isOpened) { "์ด๋ฏธ ์ด๋ฆฐ ์นธ์ ๋๋ค." } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
์ด๋ฏธ ์ด๋ฆฐ ์นธ์ ์
๋ ฅํ๋ ๊ฒฝ์ฐ ๊ฒ์์ด ๋น์ ์ ์ข
๋ฃ๋๋ ๊ฒ์ ์ด์ํ๋ค๊ณ ์๊ฐํด์.
open์ ํธ์ถํ๋ ๊ณณ์์ try-catch๋ก ์ก์๋ณผ ์๋ ์๊ฒ ์ง๋ง, sealed๋ฅผ ํ์ฉํด์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํด๋ณด๋ ๊ฑด ์ด๋จ๊น์?
openํ์ ๋, ๋น์ ์์ ์ด์ง๋ง ์ถฉ๋ถํ ๊ฒ์ ๋๋ฉ์ธ์ ๋ก์ง์ธ ๊ฒฝ์ฐ ๊ทธ์ ๋ํ ๊ฐ์ฒด๋ฅผ ์์ฑํด์ ๋ฐํํ๊ณ , ๋ฐํ ๋ฐ์ ๊ณณ์์๋ ๊ทธ ๊ฐ์ฒด์ ์ธ์คํด์ค๋ฅผ ๋น๊ตํด์ ํ ์ฒ๋ฆฌ๋ฅผ ํด๋ ์ข๊ฒ ์ด์.
sealed interface OpenResult {
object Success: OpenResult
object AlreadyOpendSpot: OpenResult
}
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
openSpot์์ OpenResult๋ฅผ ๋ฐํํ๋๋ก ๋ณ๊ฒฝํ๊ณ , ์ด๋ฅผ ํตํด Game์ ์ข
๋ฃ ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ๋๋ก ๋ณ๊ฒฝํด ์ฃผ์์ต๋๋ค!
AlreadyOpen์ ๊ฒฝ์ฐ, ์ด๋ฏธ ์ด๋ฆฐ ์นธ์ด๋ผ๋ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ๊ณ ๊ณ์ ์งํํ ์ ์๊ฒ ๋ก์ง๋ ๋ณ๊ฒฝํด ์ฃผ์์ต๋๋ค.
|
||
class FieldResponse(private val field: Field) { | ||
fun toFormattedStringInitialField(): String { | ||
return field.lines.joinToString("\n") { line -> | ||
line.spots.joinToString(" ") { spot -> | ||
if (spot.isMine()) { | ||
"*" | ||
} else { | ||
getNearbyMineCount(spot as SafeSpot) | ||
}.toString() | ||
fun toFormattedStringField(): String { | ||
val fieldInfo = field.getFieldInfo() | ||
val positions = generatePositions(fieldInfo.getWidth(), fieldInfo.getHeight()) | ||
|
||
return formatField(positions) | ||
} | ||
|
||
private fun generatePositions( | ||
width: Int, | ||
height: Int, | ||
): List<Position> { | ||
return (1..width).flatMap { x -> | ||
(1..height).map { y -> | ||
Position(x, y) | ||
} | ||
} | ||
} | ||
|
||
private fun getNearbyMineCount(spot: SafeSpot): String { | ||
return spot.nearbyMineCount.toString() | ||
private fun formatField(positions: List<Position>): String { | ||
return positions.groupBy { it.y } | ||
.map { (_, positionsInRow) -> | ||
positionsInRow.joinToString(" ") { position -> | ||
formatSpot(field.getSpot(position)) | ||
} | ||
}.joinToString("\n") | ||
} | ||
|
||
private fun formatSpot(spot: Spot): String { | ||
if (spot.isOpened()) { | ||
return if (spot is SafeSpot) { | ||
spot.nearbyMineCount.toString() | ||
} else { | ||
"*" | ||
} | ||
} | ||
return "C" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
์๋ต ๊ฐ์ฒด ์์ฒด์์ ์ฝ์ ๋ทฐ๋ฅผ ๊ทธ๋ ค๋ด๋ ๊ฑด ์กฐ๊ธ ์ด์ํ๋จ ์๊ฐ์ด ๋๋ค์!
๊ฐ์ ์ ๋ฌ๋ง ํ๊ณ , ๋ทฐ๋ฅผ ๊ทธ๋ ค๋ด๋ ๊ณณ์ ๋ทฐ์์ ์ญํ ์ ์ํํ๋๋ก ๋ถ๋ฆฌํด๋ณด์
๋ ์ข๊ฒ ์ด์!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
๐
์ ๋ ์กฐ๊ธ ๋ค๋ฅด๊ฒ ๋ณด์๋๋ฐ์,
VIew๋ '์ด๋์ ๋ณด์ฌ์ค ๊ฒ์ธ๊ฐ'์ด๊ณ , Response๋ '์ด๋ป๊ฒ ๋ณด์ฌ์ค ๊ฒ์ธ๊ฐ'์ ์ฑ
์์ ๊ฐ๊ฐ ๋งก๊ณ ์๋ค๊ณ ์๊ฐํ์ด์!
๊ทธ๋์ ํด๋น Veiw์ ๋ง๋ ์ถ๋ ฅ ํ์์ผ๋ก์ ๋ณ๊ฒฝ์ Response์ ๋ฉ์๋๋ฅผ ํตํด ์ฒ๋ฆฌํ๊ณ ,
์ด๋ฅผ ํตํด View ๋ ์ด์ด๊น์ง ๋๋ฉ์ธ์ด ๋
ธ์ถ๋๋ ๊ฒ์ ๋ง์ ๋๋ฉ์ธ์ ์บก์ํ๋ฅผ ์ ์งํ๋ ์ฅ์ ๋ ์๋ค๊ณ ์๊ฐํ์ต๋๋ค.!
/* | ||
1 2 3 4 x | ||
* 1 0 0 1 C 1 0 0 | ||
2 2 2 1 -> 2 C 2 2 1 | ||
1 * 2 * 3 C C C C | ||
y | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ํ ์คํธ ์ฝ๋๋ฅผ ๋ถ์ฐ ์ค๋ช ํด์ฃผ๋, ์๊ฐ์ ํํ์ ๋์์ฃผ๋ ์ฃผ์ ๋๋ฌด ์ข๋ค์! ๐๐
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ํผ๋๋ฐฑ ๋ฐ์ ๊ณ ์ ๋ง์ผ์
จ์ด์ ๐
์ง๋ขฐ์ฐพ๊ธฐ ๋ฏธ์
์ ๋๋ฌด ์ ๊ตฌํํด์ฃผ์
์ ํฌ๊ฒ ๋ ํผ๋๋ฐฑ ๋๋ฆด ๋ถ๋ถ์ด ์์๋ค์!
๋ค์ ๋ฏธ์
์ ๋ฆฌํฉํฐ๋ง ๋ฏธ์
์ด๋ผ, ๋ ๊ตฌํํ๊ณ ์ถ์ผ์ ๋ถ๋ถ์ด ์์ผ์๋ค๋ฉด ๋ฐ์ ํ ๋ฆฌ๋ทฐ ์์ฒญ ๋ถํ๋๋ฆฌ๊ณ , ์ด๋ง ๋ง๋ฌด๋ฆฌ ํ๊ณ ์ถ์ผ์๋ค๋ฉด DM์ด๋ ์ฝ๋ฉํธ ๋ถํ๋๋ ค์!
val position = Position(1, 1) | ||
val nearbyPositions = position.nearbyPositions() | ||
|
||
nearbyPositions.size shouldBe 8 | ||
nearbyPositions shouldContain Position(0, 0) | ||
nearbyPositions shouldContain Position(0, 1) | ||
nearbyPositions shouldContain Position(0, 2) | ||
nearbyPositions shouldContain Position(1, 0) | ||
nearbyPositions shouldContain Position(1, 2) | ||
nearbyPositions shouldContain Position(2, 0) | ||
nearbyPositions shouldContain Position(2, 1) | ||
nearbyPositions shouldContain Position(2, 2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
๊ธฐ๋๊ฐ์ธ ์ขํ๋ฅผ set์ผ๋ก ๋ด์, set๋ set์ผ๋ก ๊ฐ์ ๋น๊ตํด ํ ์คํธ๋ฅผ ํด๋ณด์๋ ์ข๊ฒ ์ด์!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
set๊ณผ set ๋น๊ต๋ ๊ฐ๋จํ๊ฒ shouldBe๋ก ๊ฐ๋ฅํ๊ตฐ์..! ๋ณ๊ฒฝํ์ต๋๋ค!
b9f4f1b
} | ||
openTargetSpot(it as SafeSpot) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as? ๋ก nullable ์บ์คํ ์ ํ ๋ค, null ์ฒ๋ฆฌ๋ฅผ ํ๋ ํํ๋ก ๋ก์ง์ ๊ตฌ์ฑํด๋ด๋ ์ข๊ฒ ์ด์!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fun openSpot(position: Position): OpenResult {
val targetSpot =
spots[position]?.let {
if (it.isMine()) {
return OpenResult.GameOver
}
it
} as SafeSpot
val openResult = targetSpot.open()
targetSpot.calculateNearbyMineCount(minePositions)
checkAndOpenNearbySpot(targetSpot)
return openResult
}
์ด๋ฐ ์์ผ๋ก let์ ํตํด null์ด ์๋ spot์์๋ง ๋๋จธ์ง ๋ก์ง์ ์คํํ๋๋ก ๋ฐ๊พธ์ด ์ฃผ์์ต๋๋ค
var nearbyMineCount: Int = 0 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
์ธ๋ถ์์๋ ์ด ํ๋๋ฅผ ์ฌํ ๋น ํ์ง ๋ชปํ๋๋ก, setter๋ฅผ private์ผ๋ก ๋ง์๋ณด๋ ๊ฑด ์ด๋จ๊น์?
์ฝํ๋ฆฐ ํ๋กํผํฐ์ ๋ํ ๋ฌธ๋ฒ์ ๊ณต์ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํด๋ณด์ธ์!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nearbyMineCount์ private set ์ ์ฉํ์ต๋๋ค! d9995d5
fun getFieldInfo(): FieldInfo { | ||
return fieldInfo |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
์ด ํจ์๋ fieldInfo ๋ฉค๋ฒ์ private์ ์ง์ ์ธ๋ถ์ ํ๋กํผํฐ๋ฅผ ๊ณต๊ฐํ๋ ํํ๋ก ์ ๊ฑฐํด๋ณผ ์ ์๊ฒ ์ด์!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
๋ถํ์ํ getter๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ํ๋์ private์ ์ ๊ฑฐํ๋ ๋ฐฉ์์ผ๋ก ๋ณ๊ฒฝํ์ต๋๋ค! d7db7a3
if (!spot.isOpened()) { | ||
openSpot(it) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spot ๊ฐ์ฒด์ isNotOpened() ํน์ isClosed() ํจ์๋ฅผ ์ถ๊ฐํด์ค๋ ์ข๊ฒ ๋ค๋ ์๊ฐ์ด ๋๋ค์!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ํ์คํ ๋ถ์ ๋ฌธ์ ์ฐ๋ ๊ฒ๋ณด๋จ isClosed๋ฅผ ๋ง๋ค์ด ์ฌ์ฉํ๋ ํธ์ด ํจ์ฌ ๋ ๊ฐ๋ ์ฑ์ด ์ข์ ๋ณด์ด๋ค์! 2bb8cf2
@malibinYun ์ด์ ํ๋ ๋ฏธ์
์ต๋ํ ๊น๋ํ๊ฒ ๋๋ด๊ณ ์ถ์ด ๋จ๊ฒจ์ฃผ์ ๋ฆฌ๋ทฐ์ ๋ํ ํผ๋๋ฐฑ ๋ฐ์ํ์ต๋๋ค! |
์๋ ํ์ธ์~! ์ง๋ขฐ ์ฐพ๊ธฐ 3๋จ๊ณ ์ ์ถํฉ๋๋ค!
๋ง์ฐฌ๊ฐ์ง๋ก ์ง๋ ๋จ๊ณ์ ๋ํ ํผ๋๋ฐฑ ๋ฐ์ & 3๋จ๊ณ ์๊ตฌ์ฌํญ ๊ตฌํํ์ต๋๋ค!
๊ฒ์ํ ๋๋ ๋ฅผ ์ถ๊ฐ๋ก ๋ง๋๋ ๋ฐฉ์๊ณผ ์ขํ๋ฅผ ๋ฏธ๋ฆฌ ์์ฑ ํ ์์ด ์ง๋ขฐ ์์น๋ฅผ ์ ํ๋ ๋ฐฉ์์ ๋ฏธ์ฒ ์๊ฐํ์ง ๋ชปํ์๋๋ฐ
ํ์คํ ๋ก์ง์ ๋ณต์ก๋๊ฐ ์ค์ด๋ค์๋ค์ ๐
๋ง์ง๋ง๊น์ง ์ ๋ถํ๋๋ ค์ ๐