From 948bb17e3d6abce119edd4f2a4ec4d40c4a827be Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Wed, 29 May 2024 02:20:24 +0900 Subject: [PATCH 01/23] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 08a8c8a..795b399 100644 --- a/README.md +++ b/README.md @@ -1 +1,11 @@ -# android-omok-precourse \ No newline at end of file +# android-omok-precourse + +### 기능 목록 +- 수는 검은돌, 흰돌을 번갈아가며 놓을 수 있다. +- 가로, 세로, 대각선에서 같은 색상의 돌이 5개 이상 놓이면, 해당 색상의 돌이 승리하고, 게임이 종료된다. + +### 요구사항 +- build.gradle.kts 파일을 변경하지 않는다. +- 테스트 코드를 사용하여 기능 목록이 정상적으로 작동하는지 테스트한다. +- 함수 라인이 15라인을 넘어가지 않도록 구현한다. +- 예외 처리를 통해 프로그램의 강제 종료를 방지한다. \ No newline at end of file From 4f93b7c6dee838b0435a41ce621cd0f426566cf2 Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Wed, 29 May 2024 17:32:32 +0900 Subject: [PATCH 02/23] =?UTF-8?q?feat:=20=EA=B2=80=EC=9D=80=EB=8F=8C?= =?UTF-8?q?=EA=B3=BC=20=ED=9D=B0=EB=8F=8C=EC=9D=84=20=EB=B2=88=EA=B0=88?= =?UTF-8?q?=EC=95=84=EA=B0=80=EB=A9=B0=20=EB=86=93=EC=9D=84=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 2 +- .../main/java/nextstep/omok/MainActivity.kt | 23 ------- .../main/java/nextstep/omok/OmokContract.kt | 33 ++++++++++ .../java/nextstep/omok/model/GameState.kt | 6 ++ .../nextstep/omok/model/IntersectionState.kt | 7 +++ .../java/nextstep/omok/model/OmokModel.kt | 43 +++++++++++++ .../main/java/nextstep/omok/model/Player.kt | 6 ++ .../nextstep/omok/presenter/OmokPresenter.kt | 31 ++++++++++ .../java/nextstep/omok/view/MainActivity.kt | 61 +++++++++++++++++++ 9 files changed, 188 insertions(+), 24 deletions(-) delete mode 100644 app/src/main/java/nextstep/omok/MainActivity.kt create mode 100644 app/src/main/java/nextstep/omok/OmokContract.kt create mode 100644 app/src/main/java/nextstep/omok/model/GameState.kt create mode 100644 app/src/main/java/nextstep/omok/model/IntersectionState.kt create mode 100644 app/src/main/java/nextstep/omok/model/OmokModel.kt create mode 100644 app/src/main/java/nextstep/omok/model/Player.kt create mode 100644 app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt create mode 100644 app/src/main/java/nextstep/omok/view/MainActivity.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 250f3db..69698ba 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -13,7 +13,7 @@ android:theme="@style/Theme.Omok" tools:targetApi="31"> diff --git a/app/src/main/java/nextstep/omok/MainActivity.kt b/app/src/main/java/nextstep/omok/MainActivity.kt deleted file mode 100644 index e6cc7b8..0000000 --- a/app/src/main/java/nextstep/omok/MainActivity.kt +++ /dev/null @@ -1,23 +0,0 @@ -package nextstep.omok - -import android.os.Bundle -import android.widget.ImageView -import android.widget.TableLayout -import android.widget.TableRow -import androidx.appcompat.app.AppCompatActivity -import androidx.core.view.children - -class MainActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) - - val board = findViewById(R.id.board) - board - .children - .filterIsInstance() - .flatMap { it.children } - .filterIsInstance() - .forEach { view -> view.setOnClickListener { view.setImageResource(R.drawable.black_stone) } } - } -} diff --git a/app/src/main/java/nextstep/omok/OmokContract.kt b/app/src/main/java/nextstep/omok/OmokContract.kt new file mode 100644 index 0000000..0744a82 --- /dev/null +++ b/app/src/main/java/nextstep/omok/OmokContract.kt @@ -0,0 +1,33 @@ +package nextstep.omok + +import nextstep.omok.model.GameState +import nextstep.omok.model.IntersectionState +import nextstep.omok.model.Player + +interface OmokContract { + interface OmokView { + fun showTurn(currentTurn: Int) + + fun placeStone(rowIndex: Int, colIndex: Int, playerType: Player) + + fun showWinner(winner: Player) + } + + interface OmokModel { + fun togglePlayer() + fun updateBoard(rowIndex: Int, colIndex: Int, stone: IntersectionState) + fun getPlayer(): Player + fun updateGameStatus(gameStatus: GameState) + fun addTurnCount() + } + + interface OmokPresenter { + fun onIntersectionClick(rowIndex: Int, colIndex: Int) + // Player에 맞는 돌을 놓는다. + // turn이 9이상일 때부터, 게임이 종료되었는지 판단한다. + + fun onGameEnd(): Boolean + // 승자를 표시한다. + // 더 이상 게임을 진행할 수 없다. + } +} \ No newline at end of file diff --git a/app/src/main/java/nextstep/omok/model/GameState.kt b/app/src/main/java/nextstep/omok/model/GameState.kt new file mode 100644 index 0000000..106a31a --- /dev/null +++ b/app/src/main/java/nextstep/omok/model/GameState.kt @@ -0,0 +1,6 @@ +package nextstep.omok.model + +sealed class GameState { + data object OnGoing : GameState() + data object End : GameState() +} diff --git a/app/src/main/java/nextstep/omok/model/IntersectionState.kt b/app/src/main/java/nextstep/omok/model/IntersectionState.kt new file mode 100644 index 0000000..5ef3883 --- /dev/null +++ b/app/src/main/java/nextstep/omok/model/IntersectionState.kt @@ -0,0 +1,7 @@ +package nextstep.omok.model + +sealed class IntersectionState { + data object Empty: IntersectionState() + data object OnWhiteStone: IntersectionState() + data object OnBlackStone: IntersectionState() +} diff --git a/app/src/main/java/nextstep/omok/model/OmokModel.kt b/app/src/main/java/nextstep/omok/model/OmokModel.kt new file mode 100644 index 0000000..2cbaf2b --- /dev/null +++ b/app/src/main/java/nextstep/omok/model/OmokModel.kt @@ -0,0 +1,43 @@ +package nextstep.omok.model + +import nextstep.omok.OmokContract + +class OmokModel: OmokContract.OmokModel { + private var currentPlayer: Player = Player.WithBlackStone + private val board: MutableList> = mutableListOf() + private var turn: Int = 0 + + init { + for(i in 0..14) { + val oneDimensionList = mutableListOf() + for(j in 0..14) { + oneDimensionList.add(IntersectionState.Empty) + } + board.add(oneDimensionList) + } + } + + override fun togglePlayer() { + currentPlayer = when(currentPlayer) { + Player.WithBlackStone -> Player.WithWhiteStone + Player.WithWhiteStone -> Player.WithBlackStone + } + } + + override fun updateBoard(rowIndex: Int, colIndex: Int, stone: IntersectionState) { + board[rowIndex][colIndex] = stone + } + + override fun getPlayer(): Player { + return currentPlayer + } + + override fun updateGameStatus(gameStatus: GameState) { + TODO("Not yet implemented") + } + + override fun addTurnCount() { + TODO("Not yet implemented") + } + +} \ No newline at end of file diff --git a/app/src/main/java/nextstep/omok/model/Player.kt b/app/src/main/java/nextstep/omok/model/Player.kt new file mode 100644 index 0000000..543dcc1 --- /dev/null +++ b/app/src/main/java/nextstep/omok/model/Player.kt @@ -0,0 +1,6 @@ +package nextstep.omok.model + +sealed class Player { + data object WithWhiteStone: Player() + data object WithBlackStone: Player() +} diff --git a/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt b/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt new file mode 100644 index 0000000..69771eb --- /dev/null +++ b/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt @@ -0,0 +1,31 @@ +package nextstep.omok.presenter + +import nextstep.omok.OmokContract +import nextstep.omok.model.IntersectionState +import nextstep.omok.model.Player + +class OmokPresenter( + private var activity: OmokContract.OmokView, + private var model: OmokContract.OmokModel +) : OmokContract.OmokPresenter { + override fun onIntersectionClick(rowIndex: Int, colIndex: Int) { + val stone = if (model.getPlayer() == Player.WithWhiteStone) { + IntersectionState.OnWhiteStone + } else { + IntersectionState.OnBlackStone + } + + model.updateBoard(rowIndex, colIndex, stone) + activity.placeStone( + rowIndex = rowIndex, + colIndex = colIndex, + playerType = model.getPlayer() + ) + model.togglePlayer() + } + + override fun onGameEnd(): Boolean { + TODO("Not yet implemented") + } + +} \ No newline at end of file diff --git a/app/src/main/java/nextstep/omok/view/MainActivity.kt b/app/src/main/java/nextstep/omok/view/MainActivity.kt new file mode 100644 index 0000000..33d5a28 --- /dev/null +++ b/app/src/main/java/nextstep/omok/view/MainActivity.kt @@ -0,0 +1,61 @@ +package nextstep.omok.view + +import android.os.Bundle +import android.widget.ImageView +import android.widget.TableLayout +import android.widget.TableRow +import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.children +import nextstep.omok.OmokContract +import nextstep.omok.R +import nextstep.omok.model.OmokModel +import nextstep.omok.model.Player +import nextstep.omok.presenter.OmokPresenter + +class MainActivity : AppCompatActivity(), OmokContract.OmokView { + + private lateinit var presenter: OmokContract.OmokPresenter + private lateinit var board: TableLayout + private lateinit var rows: List + private lateinit var imageViews: MutableList> + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + presenter = OmokPresenter(activity = this, model = OmokModel()) + board = findViewById(R.id.board) + rows = board.children.filterIsInstance().toList() + imageViews = mutableListOf() + rows.forEachIndexed { rowIndex, tableRow -> + imageViews.add(rowIndex, tableRow.children.filterIsInstance().toList()) + } + + rows.forEachIndexed { rowIndex, _ -> + imageViews[rowIndex].forEachIndexed { colIndex, imageView -> + imageView.setOnClickListener { + presenter.onIntersectionClick(rowIndex = rowIndex, colIndex = colIndex) + } + } + } + } + + override fun showTurn(currentTurn: Int) { + TODO("Not yet implemented") + } + + override fun placeStone(rowIndex: Int, colIndex: Int, playerType: Player) { + val stone = if (playerType == Player.WithWhiteStone) { + R.drawable.white_stone + } else { + R.drawable.black_stone + } + + imageViews[rowIndex][colIndex].setImageResource(stone) + + } + + override fun showWinner(winner: Player) { + TODO("Not yet implemented") + } +} From 102f1a81f3f22970d672506f72e1a911ee401ac5 Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Wed, 29 May 2024 21:14:14 +0900 Subject: [PATCH 03/23] =?UTF-8?q?update:=20Player=20=EA=B0=9D=EC=B2=B4?= =?UTF-8?q?=EB=A5=BC=20=ED=86=B5=ED=95=B4=20stone=EA=B3=BC=20resourceId?= =?UTF-8?q?=EC=97=90=20=EC=A0=91=EA=B7=BC=ED=95=A0=20=EC=88=98=20=EC=9E=88?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/nextstep/omok/model/OmokModel.kt | 1 - app/src/main/java/nextstep/omok/model/Player.kt | 15 +++++++++++++-- .../nextstep/omok/presenter/OmokPresenter.kt | 16 ++-------------- .../main/java/nextstep/omok/view/MainActivity.kt | 9 +-------- 4 files changed, 16 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/nextstep/omok/model/OmokModel.kt b/app/src/main/java/nextstep/omok/model/OmokModel.kt index 2cbaf2b..fcbba13 100644 --- a/app/src/main/java/nextstep/omok/model/OmokModel.kt +++ b/app/src/main/java/nextstep/omok/model/OmokModel.kt @@ -39,5 +39,4 @@ class OmokModel: OmokContract.OmokModel { override fun addTurnCount() { TODO("Not yet implemented") } - } \ No newline at end of file diff --git a/app/src/main/java/nextstep/omok/model/Player.kt b/app/src/main/java/nextstep/omok/model/Player.kt index 543dcc1..fea0ed4 100644 --- a/app/src/main/java/nextstep/omok/model/Player.kt +++ b/app/src/main/java/nextstep/omok/model/Player.kt @@ -1,6 +1,17 @@ package nextstep.omok.model +import nextstep.omok.R + sealed class Player { - data object WithWhiteStone: Player() - data object WithBlackStone: Player() + abstract val stone: IntersectionState + abstract val resourceId: Int + data object WithWhiteStone: Player() { + override val stone = IntersectionState.OnWhiteStone + override val resourceId: Int = R.drawable.white_stone + } + + data object WithBlackStone: Player() { + override val stone = IntersectionState.OnBlackStone + override val resourceId: Int = R.drawable.black_stone + } } diff --git a/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt b/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt index 69771eb..8ec3b87 100644 --- a/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt +++ b/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt @@ -1,26 +1,14 @@ package nextstep.omok.presenter import nextstep.omok.OmokContract -import nextstep.omok.model.IntersectionState -import nextstep.omok.model.Player class OmokPresenter( private var activity: OmokContract.OmokView, private var model: OmokContract.OmokModel ) : OmokContract.OmokPresenter { override fun onIntersectionClick(rowIndex: Int, colIndex: Int) { - val stone = if (model.getPlayer() == Player.WithWhiteStone) { - IntersectionState.OnWhiteStone - } else { - IntersectionState.OnBlackStone - } - - model.updateBoard(rowIndex, colIndex, stone) - activity.placeStone( - rowIndex = rowIndex, - colIndex = colIndex, - playerType = model.getPlayer() - ) + model.updateBoard(rowIndex, colIndex, model.getPlayer().stone) + activity.placeStone(rowIndex, colIndex, model.getPlayer()) model.togglePlayer() } diff --git a/app/src/main/java/nextstep/omok/view/MainActivity.kt b/app/src/main/java/nextstep/omok/view/MainActivity.kt index 33d5a28..2227be3 100644 --- a/app/src/main/java/nextstep/omok/view/MainActivity.kt +++ b/app/src/main/java/nextstep/omok/view/MainActivity.kt @@ -45,14 +45,7 @@ class MainActivity : AppCompatActivity(), OmokContract.OmokView { } override fun placeStone(rowIndex: Int, colIndex: Int, playerType: Player) { - val stone = if (playerType == Player.WithWhiteStone) { - R.drawable.white_stone - } else { - R.drawable.black_stone - } - - imageViews[rowIndex][colIndex].setImageResource(stone) - + imageViews[rowIndex][colIndex].setImageResource(playerType.resourceId) } override fun showWinner(winner: Player) { From 6df4845199254088cf5b4cf752b4b75f3efb4413 Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 13:51:12 +0900 Subject: [PATCH 04/23] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=84=B8=EB=B6=84=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 795b399..8a2b352 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,8 @@ ### 기능 목록 - 수는 검은돌, 흰돌을 번갈아가며 놓을 수 있다. -- 가로, 세로, 대각선에서 같은 색상의 돌이 5개 이상 놓이면, 해당 색상의 돌이 승리하고, 게임이 종료된다. +- 가로, 세로, 대각선에서 같은 색상의 돌이 5개 이상 놓이면, 해당 색상의 돌이 승리한다. +- 승자가 결정되면, 게임이 종료된다. ### 요구사항 - build.gradle.kts 파일을 변경하지 않는다. From c97db02f11ceaa3031e724bcb69d7fe260da6eeb Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 13:52:15 +0900 Subject: [PATCH 05/23] =?UTF-8?q?feat:=20=EC=98=A4=EB=AA=A9=20=EC=8A=B9?= =?UTF-8?q?=EC=9E=90=20=ED=8C=90=EC=A0=95=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/nextstep/omok/OmokContract.kt | 6 +- .../java/nextstep/omok/model/OmokModel.kt | 29 ++++++-- .../nextstep/omok/presenter/OmokPresenter.kt | 24 ++++++- .../nextstep/omok/util/GameStateValidator.kt | 70 +++++++++++++++++++ 4 files changed, 120 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/nextstep/omok/util/GameStateValidator.kt diff --git a/app/src/main/java/nextstep/omok/OmokContract.kt b/app/src/main/java/nextstep/omok/OmokContract.kt index 0744a82..be88665 100644 --- a/app/src/main/java/nextstep/omok/OmokContract.kt +++ b/app/src/main/java/nextstep/omok/OmokContract.kt @@ -17,8 +17,10 @@ interface OmokContract { fun togglePlayer() fun updateBoard(rowIndex: Int, colIndex: Int, stone: IntersectionState) fun getPlayer(): Player - fun updateGameStatus(gameStatus: GameState) + fun updateGameStatus() fun addTurnCount() + fun getTurn(): Int + fun getGameState(): GameState } interface OmokPresenter { @@ -26,7 +28,7 @@ interface OmokContract { // Player에 맞는 돌을 놓는다. // turn이 9이상일 때부터, 게임이 종료되었는지 판단한다. - fun onGameEnd(): Boolean + fun onGameEnd() // 승자를 표시한다. // 더 이상 게임을 진행할 수 없다. } diff --git a/app/src/main/java/nextstep/omok/model/OmokModel.kt b/app/src/main/java/nextstep/omok/model/OmokModel.kt index fcbba13..81e9140 100644 --- a/app/src/main/java/nextstep/omok/model/OmokModel.kt +++ b/app/src/main/java/nextstep/omok/model/OmokModel.kt @@ -1,11 +1,14 @@ package nextstep.omok.model import nextstep.omok.OmokContract +import nextstep.omok.util.GameStateValidator class OmokModel: OmokContract.OmokModel { private var currentPlayer: Player = Player.WithBlackStone + private var currentGameState: GameState = GameState.OnGoing private val board: MutableList> = mutableListOf() - private var turn: Int = 0 + private var turn: Int = 1 + private val gameStateValidator : GameStateValidator by lazy { GameStateValidator() } init { for(i in 0..14) { @@ -32,11 +35,29 @@ class OmokModel: OmokContract.OmokModel { return currentPlayer } - override fun updateGameStatus(gameStatus: GameState) { - TODO("Not yet implemented") + override fun updateGameStatus() { + val winner = gameStateValidator.getWinner(board) + if (winner == null) { + return + } else { + endGame() + } } override fun addTurnCount() { - TODO("Not yet implemented") + turn++ + } + + override fun getTurn(): Int { + return turn + } + + + override fun getGameState(): GameState { + return currentGameState + } + + private fun endGame() { + currentGameState = GameState.End } } \ No newline at end of file diff --git a/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt b/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt index 8ec3b87..bf33ac5 100644 --- a/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt +++ b/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt @@ -1,6 +1,7 @@ package nextstep.omok.presenter import nextstep.omok.OmokContract +import nextstep.omok.model.GameState class OmokPresenter( private var activity: OmokContract.OmokView, @@ -9,11 +10,28 @@ class OmokPresenter( override fun onIntersectionClick(rowIndex: Int, colIndex: Int) { model.updateBoard(rowIndex, colIndex, model.getPlayer().stone) activity.placeStone(rowIndex, colIndex, model.getPlayer()) - model.togglePlayer() + + if (model.getTurn() > 8) { + model.updateGameStatus() + checkGameState() + } else { + model.togglePlayer() + model.addTurnCount() + } } - override fun onGameEnd(): Boolean { - TODO("Not yet implemented") + override fun onGameEnd() { } + private fun checkGameState() { + when (model.getGameState()) { + GameState.OnGoing -> { + model.togglePlayer() + model.addTurnCount() + } + GameState.End -> { + onGameEnd() + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/nextstep/omok/util/GameStateValidator.kt b/app/src/main/java/nextstep/omok/util/GameStateValidator.kt new file mode 100644 index 0000000..fd5ee5b --- /dev/null +++ b/app/src/main/java/nextstep/omok/util/GameStateValidator.kt @@ -0,0 +1,70 @@ +package nextstep.omok.util + +import nextstep.omok.model.IntersectionState +import nextstep.omok.model.Player + +private const val WIN_CONDITION = 5 + +class GameStateValidator { + private var board: List> = listOf() + fun getWinner(board: List>): Player? { + this.board = board + var winner: Player? = null + for (row in board.indices) { + for (col in board[row].indices) { + winner = checkBoard(col, row) + if (winner != null) + return winner + } + } + + return winner + } + + private fun checkBoard(col: Int, row: Int): Player? { + val currentIntersection = board[row][col] + if (currentIntersection == IntersectionState.Empty) + return null + + + val isConditionSatisfied = checkAllDirections(col, row, currentIntersection) + if (!isConditionSatisfied) + return null + + return when (currentIntersection) { + IntersectionState.OnBlackStone -> Player.WithBlackStone + IntersectionState.OnWhiteStone -> Player.WithWhiteStone + IntersectionState.Empty -> null + } + } + + private fun checkAllDirections( + col: Int, row: Int, currentIntersection: IntersectionState + ): Boolean { + val directions = arrayOf( + Pair(0, 1), Pair(1, 0), Pair(1, 1), Pair(1, -1), + Pair(-1, 0), Pair(0, -1), Pair(-1, -1), Pair(-1, 1) + ) + + for (direction in directions) { + val (dRow, dCol) = direction + if (checkSingleDirection(col, row, dCol, dRow, currentIntersection)) { + return true + } + } + return false + } + + private fun checkSingleDirection( + col: Int, row: Int, dCol: Int, dRow: Int, currentIntersection: IntersectionState + ): Boolean { + for (i in 0 until WIN_CONDITION) { + val nx = col + i * dCol + val ny = row + i * dRow + if (nx !in board[0].indices || ny !in board.indices || board[ny][nx] != currentIntersection) { + return false + } + } + return true + } +} \ No newline at end of file From 7be06f1ecfe1d9d4e54415d92e448d62b76d54d4 Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 14:14:38 +0900 Subject: [PATCH 06/23] =?UTF-8?q?feat:=20=EC=8A=B9=EC=9E=90=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=20=EB=B0=8F=20=EA=B2=8C=EC=9E=84=20=EC=A2=85=EB=A3=8C?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/nextstep/omok/OmokContract.kt | 2 +- .../java/nextstep/omok/model/OmokModel.kt | 2 ++ .../nextstep/omok/presenter/OmokPresenter.kt | 1 + .../java/nextstep/omok/view/MainActivity.kt | 21 +++++++++++++++++-- app/src/main/res/layout/activity_main.xml | 8 ++++++- 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/nextstep/omok/OmokContract.kt b/app/src/main/java/nextstep/omok/OmokContract.kt index be88665..0cdba7b 100644 --- a/app/src/main/java/nextstep/omok/OmokContract.kt +++ b/app/src/main/java/nextstep/omok/OmokContract.kt @@ -10,7 +10,7 @@ interface OmokContract { fun placeStone(rowIndex: Int, colIndex: Int, playerType: Player) - fun showWinner(winner: Player) + fun endGame(winner: Player) } interface OmokModel { diff --git a/app/src/main/java/nextstep/omok/model/OmokModel.kt b/app/src/main/java/nextstep/omok/model/OmokModel.kt index 81e9140..273ecb1 100644 --- a/app/src/main/java/nextstep/omok/model/OmokModel.kt +++ b/app/src/main/java/nextstep/omok/model/OmokModel.kt @@ -9,6 +9,7 @@ class OmokModel: OmokContract.OmokModel { private val board: MutableList> = mutableListOf() private var turn: Int = 1 private val gameStateValidator : GameStateValidator by lazy { GameStateValidator() } + private var winner: Player? = null init { for(i in 0..14) { @@ -40,6 +41,7 @@ class OmokModel: OmokContract.OmokModel { if (winner == null) { return } else { + this.winner = winner endGame() } } diff --git a/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt b/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt index bf33ac5..5848723 100644 --- a/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt +++ b/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt @@ -21,6 +21,7 @@ class OmokPresenter( } override fun onGameEnd() { + activity.endGame(model.getPlayer()) } private fun checkGameState() { diff --git a/app/src/main/java/nextstep/omok/view/MainActivity.kt b/app/src/main/java/nextstep/omok/view/MainActivity.kt index 2227be3..a6d4a53 100644 --- a/app/src/main/java/nextstep/omok/view/MainActivity.kt +++ b/app/src/main/java/nextstep/omok/view/MainActivity.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.widget.ImageView import android.widget.TableLayout import android.widget.TableRow +import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.core.view.children import nextstep.omok.OmokContract @@ -18,6 +19,7 @@ class MainActivity : AppCompatActivity(), OmokContract.OmokView { private lateinit var board: TableLayout private lateinit var rows: List private lateinit var imageViews: MutableList> + private lateinit var textView: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -38,6 +40,8 @@ class MainActivity : AppCompatActivity(), OmokContract.OmokView { } } } + + textView = findViewById(R.id.winner) } override fun showTurn(currentTurn: Int) { @@ -48,7 +52,20 @@ class MainActivity : AppCompatActivity(), OmokContract.OmokView { imageViews[rowIndex][colIndex].setImageResource(playerType.resourceId) } - override fun showWinner(winner: Player) { - TODO("Not yet implemented") + override fun endGame(winner: Player) { + detachClickListener() + showWinner(winner) + } + + private fun detachClickListener() { + rows.forEachIndexed { rowIndex, _ -> + imageViews[rowIndex].forEachIndexed { _, imageView -> + imageView.setOnClickListener(null) + } + } + } + + private fun showWinner(winner: Player) { + textView.text = "승자는 $winner 입니다." } } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index d809fc8..b593d6b 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,7 +1,8 @@ + android:layout_height="wrap_content" + android:orientation="vertical"> + + From badbe78eac5892eb4e9a6128bc4416f621c26d48 Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 14:30:50 +0900 Subject: [PATCH 07/23] =?UTF-8?q?feat:=20=ED=98=84=EC=9E=AC=20turn?= =?UTF-8?q?=EA=B3=BC=20player=EB=A5=BC=20=ED=91=9C=EC=8B=9C=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/nextstep/omok/OmokContract.kt | 2 +- .../java/nextstep/omok/presenter/OmokPresenter.kt | 1 + app/src/main/java/nextstep/omok/view/MainActivity.kt | 12 ++++++------ app/src/main/res/layout/activity_main.xml | 2 +- app/src/main/res/values/strings.xml | 3 +++ 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/nextstep/omok/OmokContract.kt b/app/src/main/java/nextstep/omok/OmokContract.kt index 0cdba7b..18cc796 100644 --- a/app/src/main/java/nextstep/omok/OmokContract.kt +++ b/app/src/main/java/nextstep/omok/OmokContract.kt @@ -6,7 +6,7 @@ import nextstep.omok.model.Player interface OmokContract { interface OmokView { - fun showTurn(currentTurn: Int) + fun showTurn(currentTurn: Int, currentPlayer: Player) fun placeStone(rowIndex: Int, colIndex: Int, playerType: Player) diff --git a/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt b/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt index 5848723..9a860de 100644 --- a/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt +++ b/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt @@ -18,6 +18,7 @@ class OmokPresenter( model.togglePlayer() model.addTurnCount() } + activity.showTurn(model.getTurn(), model.getPlayer()) } override fun onGameEnd() { diff --git a/app/src/main/java/nextstep/omok/view/MainActivity.kt b/app/src/main/java/nextstep/omok/view/MainActivity.kt index a6d4a53..b33b0cd 100644 --- a/app/src/main/java/nextstep/omok/view/MainActivity.kt +++ b/app/src/main/java/nextstep/omok/view/MainActivity.kt @@ -17,9 +17,9 @@ class MainActivity : AppCompatActivity(), OmokContract.OmokView { private lateinit var presenter: OmokContract.OmokPresenter private lateinit var board: TableLayout + private lateinit var notice: TextView private lateinit var rows: List private lateinit var imageViews: MutableList> - private lateinit var textView: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -27,12 +27,13 @@ class MainActivity : AppCompatActivity(), OmokContract.OmokView { presenter = OmokPresenter(activity = this, model = OmokModel()) board = findViewById(R.id.board) + notice = findViewById(R.id.notice) + rows = board.children.filterIsInstance().toList() imageViews = mutableListOf() rows.forEachIndexed { rowIndex, tableRow -> imageViews.add(rowIndex, tableRow.children.filterIsInstance().toList()) } - rows.forEachIndexed { rowIndex, _ -> imageViews[rowIndex].forEachIndexed { colIndex, imageView -> imageView.setOnClickListener { @@ -41,11 +42,10 @@ class MainActivity : AppCompatActivity(), OmokContract.OmokView { } } - textView = findViewById(R.id.winner) } - override fun showTurn(currentTurn: Int) { - TODO("Not yet implemented") + override fun showTurn(currentTurn: Int, currentPlayer: Player) { + notice.text = getString(R.string.notice_turn, currentTurn, currentPlayer) } override fun placeStone(rowIndex: Int, colIndex: Int, playerType: Player) { @@ -66,6 +66,6 @@ class MainActivity : AppCompatActivity(), OmokContract.OmokView { } private fun showWinner(winner: Player) { - textView.text = "승자는 $winner 입니다." + notice.text = getString(R.string.notice_winner, winner) } } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index b593d6b..dce92a1 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1183,7 +1183,7 @@ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ea74e97..7602a37 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,6 @@ Omok + + 현재는 %1$d번째 차례입니다. %2$s의 순서입니다. + 승자는 %1$s 입니다. From 6908421d134a2c5d88bdfc8b55a4a56d0aa926f1 Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 14:55:19 +0900 Subject: [PATCH 08/23] =?UTF-8?q?style:=20MainActivity=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/nextstep/omok/view/MainActivity.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/main/java/nextstep/omok/view/MainActivity.kt b/app/src/main/java/nextstep/omok/view/MainActivity.kt index b33b0cd..4fad860 100644 --- a/app/src/main/java/nextstep/omok/view/MainActivity.kt +++ b/app/src/main/java/nextstep/omok/view/MainActivity.kt @@ -14,7 +14,6 @@ import nextstep.omok.model.Player import nextstep.omok.presenter.OmokPresenter class MainActivity : AppCompatActivity(), OmokContract.OmokView { - private lateinit var presenter: OmokContract.OmokPresenter private lateinit var board: TableLayout private lateinit var notice: TextView @@ -41,7 +40,6 @@ class MainActivity : AppCompatActivity(), OmokContract.OmokView { } } } - } override fun showTurn(currentTurn: Int, currentPlayer: Player) { From ed4281b8d6d1d090e19fd11b454d2055021c9101 Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 17:37:12 +0900 Subject: [PATCH 09/23] =?UTF-8?q?refactor:=20OmokModel=EC=97=90=EC=84=9C?= =?UTF-8?q?=20OmokBoard=20=EA=B0=9D=EC=B2=B4=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/omok/model/OmokBoard.kt | 23 +++++++++++++++++++ .../java/nextstep/omok/model/OmokModel.kt | 22 +++++------------- 2 files changed, 29 insertions(+), 16 deletions(-) create mode 100644 app/src/main/java/nextstep/omok/model/OmokBoard.kt diff --git a/app/src/main/java/nextstep/omok/model/OmokBoard.kt b/app/src/main/java/nextstep/omok/model/OmokBoard.kt new file mode 100644 index 0000000..d44e75b --- /dev/null +++ b/app/src/main/java/nextstep/omok/model/OmokBoard.kt @@ -0,0 +1,23 @@ +package nextstep.omok.model + +class OmokBoard { + private val omokBoard: MutableList> = mutableListOf() + + init { + for(i in 0..14) { + val boardRow = mutableListOf() + for(j in 0..14) { + boardRow.add(IntersectionState.Empty) + } + omokBoard.add(boardRow) + } + } + + fun updateBoard(rowIndex: Int, colIndex: Int, stone: IntersectionState) { + omokBoard[rowIndex][colIndex] = stone + } + + fun getBoard(): List> { + return omokBoard + } +} \ No newline at end of file diff --git a/app/src/main/java/nextstep/omok/model/OmokModel.kt b/app/src/main/java/nextstep/omok/model/OmokModel.kt index 273ecb1..cccb828 100644 --- a/app/src/main/java/nextstep/omok/model/OmokModel.kt +++ b/app/src/main/java/nextstep/omok/model/OmokModel.kt @@ -3,33 +3,23 @@ package nextstep.omok.model import nextstep.omok.OmokContract import nextstep.omok.util.GameStateValidator -class OmokModel: OmokContract.OmokModel { +class OmokModel : OmokContract.OmokModel { private var currentPlayer: Player = Player.WithBlackStone private var currentGameState: GameState = GameState.OnGoing - private val board: MutableList> = mutableListOf() + private val omokBoard = OmokBoard() private var turn: Int = 1 - private val gameStateValidator : GameStateValidator by lazy { GameStateValidator() } + private val gameStateValidator: GameStateValidator by lazy { GameStateValidator() } private var winner: Player? = null - init { - for(i in 0..14) { - val oneDimensionList = mutableListOf() - for(j in 0..14) { - oneDimensionList.add(IntersectionState.Empty) - } - board.add(oneDimensionList) - } - } - override fun togglePlayer() { - currentPlayer = when(currentPlayer) { + currentPlayer = when (currentPlayer) { Player.WithBlackStone -> Player.WithWhiteStone Player.WithWhiteStone -> Player.WithBlackStone } } override fun updateBoard(rowIndex: Int, colIndex: Int, stone: IntersectionState) { - board[rowIndex][colIndex] = stone + omokBoard.updateBoard(rowIndex, colIndex, stone) } override fun getPlayer(): Player { @@ -37,7 +27,7 @@ class OmokModel: OmokContract.OmokModel { } override fun updateGameStatus() { - val winner = gameStateValidator.getWinner(board) + val winner = gameStateValidator.getWinner(omokBoard.getBoard()) if (winner == null) { return } else { From 8ee69a264a44cc328c0ac5b23d1bd2c27ee307cd Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 17:38:22 +0900 Subject: [PATCH 10/23] =?UTF-8?q?refactor:=20sealed=20class=20=EB=AA=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20-=20Player=20to=20PlayerType?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/nextstep/omok/OmokContract.kt | 10 +++++----- app/src/main/java/nextstep/omok/model/OmokModel.kt | 14 +++++++------- .../omok/model/{Player.kt => PlayerType.kt} | 6 +++--- .../java/nextstep/omok/util/GameStateValidator.kt | 12 ++++++------ .../main/java/nextstep/omok/view/MainActivity.kt | 12 ++++++------ 5 files changed, 27 insertions(+), 27 deletions(-) rename app/src/main/java/nextstep/omok/model/{Player.kt => PlayerType.kt} (76%) diff --git a/app/src/main/java/nextstep/omok/OmokContract.kt b/app/src/main/java/nextstep/omok/OmokContract.kt index 18cc796..866ffcc 100644 --- a/app/src/main/java/nextstep/omok/OmokContract.kt +++ b/app/src/main/java/nextstep/omok/OmokContract.kt @@ -2,21 +2,21 @@ package nextstep.omok import nextstep.omok.model.GameState import nextstep.omok.model.IntersectionState -import nextstep.omok.model.Player +import nextstep.omok.model.PlayerType interface OmokContract { interface OmokView { - fun showTurn(currentTurn: Int, currentPlayer: Player) + fun showTurn(currentTurn: Int, currentPlayerType: PlayerType) - fun placeStone(rowIndex: Int, colIndex: Int, playerType: Player) + fun placeStone(rowIndex: Int, colIndex: Int, playerType: PlayerType) - fun endGame(winner: Player) + fun endGame(winner: PlayerType) } interface OmokModel { fun togglePlayer() fun updateBoard(rowIndex: Int, colIndex: Int, stone: IntersectionState) - fun getPlayer(): Player + fun getPlayer(): PlayerType fun updateGameStatus() fun addTurnCount() fun getTurn(): Int diff --git a/app/src/main/java/nextstep/omok/model/OmokModel.kt b/app/src/main/java/nextstep/omok/model/OmokModel.kt index cccb828..1c26ee6 100644 --- a/app/src/main/java/nextstep/omok/model/OmokModel.kt +++ b/app/src/main/java/nextstep/omok/model/OmokModel.kt @@ -4,17 +4,17 @@ import nextstep.omok.OmokContract import nextstep.omok.util.GameStateValidator class OmokModel : OmokContract.OmokModel { - private var currentPlayer: Player = Player.WithBlackStone + private var currentPlayerType: PlayerType = PlayerType.WithBlackStone private var currentGameState: GameState = GameState.OnGoing private val omokBoard = OmokBoard() private var turn: Int = 1 private val gameStateValidator: GameStateValidator by lazy { GameStateValidator() } - private var winner: Player? = null + private var winner: PlayerType? = null override fun togglePlayer() { - currentPlayer = when (currentPlayer) { - Player.WithBlackStone -> Player.WithWhiteStone - Player.WithWhiteStone -> Player.WithBlackStone + currentPlayerType = when (currentPlayerType) { + PlayerType.WithBlackStone -> PlayerType.WithWhiteStone + PlayerType.WithWhiteStone -> PlayerType.WithBlackStone } } @@ -22,8 +22,8 @@ class OmokModel : OmokContract.OmokModel { omokBoard.updateBoard(rowIndex, colIndex, stone) } - override fun getPlayer(): Player { - return currentPlayer + override fun getPlayer(): PlayerType { + return currentPlayerType } override fun updateGameStatus() { diff --git a/app/src/main/java/nextstep/omok/model/Player.kt b/app/src/main/java/nextstep/omok/model/PlayerType.kt similarity index 76% rename from app/src/main/java/nextstep/omok/model/Player.kt rename to app/src/main/java/nextstep/omok/model/PlayerType.kt index fea0ed4..349504d 100644 --- a/app/src/main/java/nextstep/omok/model/Player.kt +++ b/app/src/main/java/nextstep/omok/model/PlayerType.kt @@ -2,15 +2,15 @@ package nextstep.omok.model import nextstep.omok.R -sealed class Player { +sealed class PlayerType { abstract val stone: IntersectionState abstract val resourceId: Int - data object WithWhiteStone: Player() { + data object WithWhiteStone: PlayerType() { override val stone = IntersectionState.OnWhiteStone override val resourceId: Int = R.drawable.white_stone } - data object WithBlackStone: Player() { + data object WithBlackStone: PlayerType() { override val stone = IntersectionState.OnBlackStone override val resourceId: Int = R.drawable.black_stone } diff --git a/app/src/main/java/nextstep/omok/util/GameStateValidator.kt b/app/src/main/java/nextstep/omok/util/GameStateValidator.kt index fd5ee5b..701b346 100644 --- a/app/src/main/java/nextstep/omok/util/GameStateValidator.kt +++ b/app/src/main/java/nextstep/omok/util/GameStateValidator.kt @@ -1,15 +1,15 @@ package nextstep.omok.util import nextstep.omok.model.IntersectionState -import nextstep.omok.model.Player +import nextstep.omok.model.PlayerType private const val WIN_CONDITION = 5 class GameStateValidator { private var board: List> = listOf() - fun getWinner(board: List>): Player? { + fun getWinner(board: List>): PlayerType? { this.board = board - var winner: Player? = null + var winner: PlayerType? = null for (row in board.indices) { for (col in board[row].indices) { winner = checkBoard(col, row) @@ -21,7 +21,7 @@ class GameStateValidator { return winner } - private fun checkBoard(col: Int, row: Int): Player? { + private fun checkBoard(col: Int, row: Int): PlayerType? { val currentIntersection = board[row][col] if (currentIntersection == IntersectionState.Empty) return null @@ -32,8 +32,8 @@ class GameStateValidator { return null return when (currentIntersection) { - IntersectionState.OnBlackStone -> Player.WithBlackStone - IntersectionState.OnWhiteStone -> Player.WithWhiteStone + IntersectionState.OnBlackStone -> PlayerType.WithBlackStone + IntersectionState.OnWhiteStone -> PlayerType.WithWhiteStone IntersectionState.Empty -> null } } diff --git a/app/src/main/java/nextstep/omok/view/MainActivity.kt b/app/src/main/java/nextstep/omok/view/MainActivity.kt index 4fad860..0c2f7fa 100644 --- a/app/src/main/java/nextstep/omok/view/MainActivity.kt +++ b/app/src/main/java/nextstep/omok/view/MainActivity.kt @@ -10,7 +10,7 @@ import androidx.core.view.children import nextstep.omok.OmokContract import nextstep.omok.R import nextstep.omok.model.OmokModel -import nextstep.omok.model.Player +import nextstep.omok.model.PlayerType import nextstep.omok.presenter.OmokPresenter class MainActivity : AppCompatActivity(), OmokContract.OmokView { @@ -42,15 +42,15 @@ class MainActivity : AppCompatActivity(), OmokContract.OmokView { } } - override fun showTurn(currentTurn: Int, currentPlayer: Player) { - notice.text = getString(R.string.notice_turn, currentTurn, currentPlayer) + override fun showTurn(currentTurn: Int, currentPlayerType: PlayerType) { + notice.text = getString(R.string.notice_turn, currentTurn, currentPlayerType) } - override fun placeStone(rowIndex: Int, colIndex: Int, playerType: Player) { + override fun placeStone(rowIndex: Int, colIndex: Int, playerType: PlayerType) { imageViews[rowIndex][colIndex].setImageResource(playerType.resourceId) } - override fun endGame(winner: Player) { + override fun endGame(winner: PlayerType) { detachClickListener() showWinner(winner) } @@ -63,7 +63,7 @@ class MainActivity : AppCompatActivity(), OmokContract.OmokView { } } - private fun showWinner(winner: Player) { + private fun showWinner(winner: PlayerType) { notice.text = getString(R.string.notice_winner, winner) } } From d0be0244bdfcafde99c00248eb2b18e1a232138f Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 17:42:10 +0900 Subject: [PATCH 11/23] =?UTF-8?q?refactor:=20OmokModel=EC=97=90=EC=84=9C?= =?UTF-8?q?=20CurrentPlayer=20=EA=B0=9D=EC=B2=B4=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/omok/model/CurrentPlayer.kt | 16 ++++++++++++++++ .../main/java/nextstep/omok/model/OmokModel.kt | 15 ++++++--------- 2 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/nextstep/omok/model/CurrentPlayer.kt diff --git a/app/src/main/java/nextstep/omok/model/CurrentPlayer.kt b/app/src/main/java/nextstep/omok/model/CurrentPlayer.kt new file mode 100644 index 0000000..cccf79f --- /dev/null +++ b/app/src/main/java/nextstep/omok/model/CurrentPlayer.kt @@ -0,0 +1,16 @@ +package nextstep.omok.model + +object CurrentPlayer { + private var currentPlayer: PlayerType = PlayerType.WithBlackStone + + fun togglePlayer() { + currentPlayer = when (currentPlayer) { + PlayerType.WithBlackStone -> PlayerType.WithWhiteStone + PlayerType.WithWhiteStone -> PlayerType.WithBlackStone + } + } + + fun getPlayer(): PlayerType { + return currentPlayer + } +} \ No newline at end of file diff --git a/app/src/main/java/nextstep/omok/model/OmokModel.kt b/app/src/main/java/nextstep/omok/model/OmokModel.kt index 1c26ee6..56b838d 100644 --- a/app/src/main/java/nextstep/omok/model/OmokModel.kt +++ b/app/src/main/java/nextstep/omok/model/OmokModel.kt @@ -4,7 +4,7 @@ import nextstep.omok.OmokContract import nextstep.omok.util.GameStateValidator class OmokModel : OmokContract.OmokModel { - private var currentPlayerType: PlayerType = PlayerType.WithBlackStone + private var currentPlayer: CurrentPlayer = CurrentPlayer private var currentGameState: GameState = GameState.OnGoing private val omokBoard = OmokBoard() private var turn: Int = 1 @@ -12,18 +12,15 @@ class OmokModel : OmokContract.OmokModel { private var winner: PlayerType? = null override fun togglePlayer() { - currentPlayerType = when (currentPlayerType) { - PlayerType.WithBlackStone -> PlayerType.WithWhiteStone - PlayerType.WithWhiteStone -> PlayerType.WithBlackStone - } + currentPlayer.togglePlayer() } - override fun updateBoard(rowIndex: Int, colIndex: Int, stone: IntersectionState) { - omokBoard.updateBoard(rowIndex, colIndex, stone) + override fun getPlayer(): PlayerType { + return currentPlayer.getPlayer() } - override fun getPlayer(): PlayerType { - return currentPlayerType + override fun updateBoard(rowIndex: Int, colIndex: Int, stone: IntersectionState) { + omokBoard.updateBoard(rowIndex, colIndex, stone) } override fun updateGameStatus() { From 8bf9203f0590d1abd716bb19042d79f57a723d0f Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 17:43:44 +0900 Subject: [PATCH 12/23] =?UTF-8?q?refactor:=20OmokBoard=EB=A5=BC=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=EC=97=90=EC=84=9C=20=EC=98=A4?= =?UTF-8?q?=EB=B8=8C=EC=A0=9D=ED=8A=B8=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/nextstep/omok/model/OmokBoard.kt | 2 +- app/src/main/java/nextstep/omok/model/OmokModel.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/nextstep/omok/model/OmokBoard.kt b/app/src/main/java/nextstep/omok/model/OmokBoard.kt index d44e75b..bad62b0 100644 --- a/app/src/main/java/nextstep/omok/model/OmokBoard.kt +++ b/app/src/main/java/nextstep/omok/model/OmokBoard.kt @@ -1,6 +1,6 @@ package nextstep.omok.model -class OmokBoard { +object OmokBoard { private val omokBoard: MutableList> = mutableListOf() init { diff --git a/app/src/main/java/nextstep/omok/model/OmokModel.kt b/app/src/main/java/nextstep/omok/model/OmokModel.kt index 56b838d..77dd1f9 100644 --- a/app/src/main/java/nextstep/omok/model/OmokModel.kt +++ b/app/src/main/java/nextstep/omok/model/OmokModel.kt @@ -6,7 +6,7 @@ import nextstep.omok.util.GameStateValidator class OmokModel : OmokContract.OmokModel { private var currentPlayer: CurrentPlayer = CurrentPlayer private var currentGameState: GameState = GameState.OnGoing - private val omokBoard = OmokBoard() + private val omokBoard = OmokBoard private var turn: Int = 1 private val gameStateValidator: GameStateValidator by lazy { GameStateValidator() } private var winner: PlayerType? = null From a3cec69974308fc45a60584590cbe108efcb77a5 Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 17:48:19 +0900 Subject: [PATCH 13/23] =?UTF-8?q?style:=20=ED=95=A8=EC=88=98=20=EC=88=9C?= =?UTF-8?q?=EC=84=9C=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/nextstep/omok/OmokContract.kt | 11 ++++++-- .../java/nextstep/omok/model/OmokModel.kt | 26 ++++++++++++------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/nextstep/omok/OmokContract.kt b/app/src/main/java/nextstep/omok/OmokContract.kt index 866ffcc..2039aa8 100644 --- a/app/src/main/java/nextstep/omok/OmokContract.kt +++ b/app/src/main/java/nextstep/omok/OmokContract.kt @@ -14,12 +14,19 @@ interface OmokContract { } interface OmokModel { + /* currentPlayer 관련 함수 */ fun togglePlayer() - fun updateBoard(rowIndex: Int, colIndex: Int, stone: IntersectionState) fun getPlayer(): PlayerType - fun updateGameStatus() + + /* omokBoard 관련 함수 */ + fun updateBoard(rowIndex: Int, colIndex: Int, stone: IntersectionState) + + /* turn 관련 함수 */ fun addTurnCount() fun getTurn(): Int + + /* currentGameState 관련 함수 */ + fun updateGameStatus() fun getGameState(): GameState } diff --git a/app/src/main/java/nextstep/omok/model/OmokModel.kt b/app/src/main/java/nextstep/omok/model/OmokModel.kt index 77dd1f9..0d73990 100644 --- a/app/src/main/java/nextstep/omok/model/OmokModel.kt +++ b/app/src/main/java/nextstep/omok/model/OmokModel.kt @@ -5,12 +5,13 @@ import nextstep.omok.util.GameStateValidator class OmokModel : OmokContract.OmokModel { private var currentPlayer: CurrentPlayer = CurrentPlayer - private var currentGameState: GameState = GameState.OnGoing private val omokBoard = OmokBoard private var turn: Int = 1 + private var currentGameState: GameState = GameState.OnGoing private val gameStateValidator: GameStateValidator by lazy { GameStateValidator() } private var winner: PlayerType? = null + /* currentPlayer 관련 함수 */ override fun togglePlayer() { currentPlayer.togglePlayer() } @@ -19,20 +20,14 @@ class OmokModel : OmokContract.OmokModel { return currentPlayer.getPlayer() } + + /* omokBoard 관련 함수 */ override fun updateBoard(rowIndex: Int, colIndex: Int, stone: IntersectionState) { omokBoard.updateBoard(rowIndex, colIndex, stone) } - override fun updateGameStatus() { - val winner = gameStateValidator.getWinner(omokBoard.getBoard()) - if (winner == null) { - return - } else { - this.winner = winner - endGame() - } - } + /* turn 관련 함수 */ override fun addTurnCount() { turn++ } @@ -42,6 +37,17 @@ class OmokModel : OmokContract.OmokModel { } + /* currentGameState 관련 함수 */ + override fun updateGameStatus() { + val winner = gameStateValidator.getWinner(omokBoard.getBoard()) + if (winner == null) { + return + } else { + this.winner = winner + endGame() + } + } + override fun getGameState(): GameState { return currentGameState } From c1db1fd3e26f252d7757ccfe0097387b3f0af421 Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 19:04:24 +0900 Subject: [PATCH 14/23] =?UTF-8?q?refactor:=20OmokPresenter=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=84=B8=EB=B6=84=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nextstep/omok/presenter/OmokPresenter.kt | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt b/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt index 9a860de..7dd86de 100644 --- a/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt +++ b/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt @@ -8,32 +8,42 @@ class OmokPresenter( private var model: OmokContract.OmokModel ) : OmokContract.OmokPresenter { override fun onIntersectionClick(rowIndex: Int, colIndex: Int) { + updateBoard(rowIndex, colIndex) + checkWinnerExist() + } + + private fun updateBoard(rowIndex: Int, colIndex: Int) { model.updateBoard(rowIndex, colIndex, model.getPlayer().stone) activity.placeStone(rowIndex, colIndex, model.getPlayer()) + } + private fun checkWinnerExist() { if (model.getTurn() > 8) { model.updateGameStatus() - checkGameState() + checkCurrentGameState() } else { - model.togglePlayer() - model.addTurnCount() + onGameOnGoing() } - activity.showTurn(model.getTurn(), model.getPlayer()) - } - - override fun onGameEnd() { - activity.endGame(model.getPlayer()) } - private fun checkGameState() { + private fun checkCurrentGameState() { when (model.getGameState()) { GameState.OnGoing -> { - model.togglePlayer() - model.addTurnCount() + onGameOnGoing() } GameState.End -> { onGameEnd() } } } + + private fun onGameOnGoing() { + model.togglePlayer() + model.addTurnCount() + activity.showTurn(model.getTurn(), model.getPlayer()) + } + + private fun onGameEnd() { + activity.endGame(model.getPlayer()) + } } \ No newline at end of file From 9a193159945e7d7fa67b94c09e14b08ca367c3fd Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 19:04:33 +0900 Subject: [PATCH 15/23] =?UTF-8?q?style:=20=EC=BD=94=EB=93=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/nextstep/omok/OmokContract.kt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/src/main/java/nextstep/omok/OmokContract.kt b/app/src/main/java/nextstep/omok/OmokContract.kt index 2039aa8..43909cf 100644 --- a/app/src/main/java/nextstep/omok/OmokContract.kt +++ b/app/src/main/java/nextstep/omok/OmokContract.kt @@ -7,9 +7,7 @@ import nextstep.omok.model.PlayerType interface OmokContract { interface OmokView { fun showTurn(currentTurn: Int, currentPlayerType: PlayerType) - fun placeStone(rowIndex: Int, colIndex: Int, playerType: PlayerType) - fun endGame(winner: PlayerType) } @@ -34,9 +32,5 @@ interface OmokContract { fun onIntersectionClick(rowIndex: Int, colIndex: Int) // Player에 맞는 돌을 놓는다. // turn이 9이상일 때부터, 게임이 종료되었는지 판단한다. - - fun onGameEnd() - // 승자를 표시한다. - // 더 이상 게임을 진행할 수 없다. } } \ No newline at end of file From 288908756d19c5701a50728f2204a7393652e16e Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 19:05:47 +0900 Subject: [PATCH 16/23] =?UTF-8?q?refactor:=20GameStateValidator=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A5=BC=20=EC=98=A4=EB=B8=8C?= =?UTF-8?q?=EC=A0=9D=ED=8A=B8=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/nextstep/omok/model/OmokModel.kt | 2 +- app/src/main/java/nextstep/omok/util/GameStateValidator.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/nextstep/omok/model/OmokModel.kt b/app/src/main/java/nextstep/omok/model/OmokModel.kt index 0d73990..088ded4 100644 --- a/app/src/main/java/nextstep/omok/model/OmokModel.kt +++ b/app/src/main/java/nextstep/omok/model/OmokModel.kt @@ -8,7 +8,7 @@ class OmokModel : OmokContract.OmokModel { private val omokBoard = OmokBoard private var turn: Int = 1 private var currentGameState: GameState = GameState.OnGoing - private val gameStateValidator: GameStateValidator by lazy { GameStateValidator() } + private val gameStateValidator: GameStateValidator by lazy { GameStateValidator } private var winner: PlayerType? = null /* currentPlayer 관련 함수 */ diff --git a/app/src/main/java/nextstep/omok/util/GameStateValidator.kt b/app/src/main/java/nextstep/omok/util/GameStateValidator.kt index 701b346..3c00a6b 100644 --- a/app/src/main/java/nextstep/omok/util/GameStateValidator.kt +++ b/app/src/main/java/nextstep/omok/util/GameStateValidator.kt @@ -5,7 +5,7 @@ import nextstep.omok.model.PlayerType private const val WIN_CONDITION = 5 -class GameStateValidator { +object GameStateValidator { private var board: List> = listOf() fun getWinner(board: List>): PlayerType? { this.board = board From 2f3ba2a1592447e658a42522f002e8f37e821889 Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 19:25:05 +0900 Subject: [PATCH 17/23] =?UTF-8?q?refactor:=20OmokModel=20=EB=A9=A4?= =?UTF-8?q?=EB=B2=84=20=EB=B3=80=EC=88=98=20winner=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/nextstep/omok/model/OmokModel.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/main/java/nextstep/omok/model/OmokModel.kt b/app/src/main/java/nextstep/omok/model/OmokModel.kt index 088ded4..c1e412a 100644 --- a/app/src/main/java/nextstep/omok/model/OmokModel.kt +++ b/app/src/main/java/nextstep/omok/model/OmokModel.kt @@ -9,7 +9,6 @@ class OmokModel : OmokContract.OmokModel { private var turn: Int = 1 private var currentGameState: GameState = GameState.OnGoing private val gameStateValidator: GameStateValidator by lazy { GameStateValidator } - private var winner: PlayerType? = null /* currentPlayer 관련 함수 */ override fun togglePlayer() { @@ -43,7 +42,6 @@ class OmokModel : OmokContract.OmokModel { if (winner == null) { return } else { - this.winner = winner endGame() } } From a05c3f5fe665d7fa3dd9a1b32a77d0f74507c48a Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 19:56:39 +0900 Subject: [PATCH 18/23] =?UTF-8?q?refactor:=20=EC=8A=B9=EC=9E=90=20?= =?UTF-8?q?=ED=8C=90=EC=A0=95=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/nextstep/omok/OmokContract.kt | 2 +- .../java/nextstep/omok/model/OmokModel.kt | 7 ++-- .../nextstep/omok/presenter/OmokPresenter.kt | 2 +- .../nextstep/omok/util/GameStateValidator.kt | 32 +++++++------------ 4 files changed, 16 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/nextstep/omok/OmokContract.kt b/app/src/main/java/nextstep/omok/OmokContract.kt index 43909cf..3e22984 100644 --- a/app/src/main/java/nextstep/omok/OmokContract.kt +++ b/app/src/main/java/nextstep/omok/OmokContract.kt @@ -24,7 +24,7 @@ interface OmokContract { fun getTurn(): Int /* currentGameState 관련 함수 */ - fun updateGameStatus() + fun checkWinnerExist() fun getGameState(): GameState } diff --git a/app/src/main/java/nextstep/omok/model/OmokModel.kt b/app/src/main/java/nextstep/omok/model/OmokModel.kt index c1e412a..2b5259f 100644 --- a/app/src/main/java/nextstep/omok/model/OmokModel.kt +++ b/app/src/main/java/nextstep/omok/model/OmokModel.kt @@ -37,11 +37,8 @@ class OmokModel : OmokContract.OmokModel { /* currentGameState 관련 함수 */ - override fun updateGameStatus() { - val winner = gameStateValidator.getWinner(omokBoard.getBoard()) - if (winner == null) { - return - } else { + override fun checkWinnerExist() { + if (gameStateValidator.isWinnerExist(omokBoard.getBoard())) { endGame() } } diff --git a/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt b/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt index 7dd86de..98c34cb 100644 --- a/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt +++ b/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt @@ -19,7 +19,7 @@ class OmokPresenter( private fun checkWinnerExist() { if (model.getTurn() > 8) { - model.updateGameStatus() + model.checkWinnerExist() checkCurrentGameState() } else { onGameOnGoing() diff --git a/app/src/main/java/nextstep/omok/util/GameStateValidator.kt b/app/src/main/java/nextstep/omok/util/GameStateValidator.kt index 3c00a6b..3a3ddd8 100644 --- a/app/src/main/java/nextstep/omok/util/GameStateValidator.kt +++ b/app/src/main/java/nextstep/omok/util/GameStateValidator.kt @@ -1,51 +1,43 @@ package nextstep.omok.util import nextstep.omok.model.IntersectionState -import nextstep.omok.model.PlayerType private const val WIN_CONDITION = 5 object GameStateValidator { private var board: List> = listOf() - fun getWinner(board: List>): PlayerType? { + private val directions = arrayOf(Pair(0, 1), Pair(1, 0), Pair(1, 1), Pair(1, -1),) + + fun isWinnerExist(board: List>): Boolean { this.board = board - var winner: PlayerType? = null for (row in board.indices) { for (col in board[row].indices) { - winner = checkBoard(col, row) - if (winner != null) - return winner + if (checkBoard(col, row)) + return true } } - - return winner + return false } - private fun checkBoard(col: Int, row: Int): PlayerType? { + private fun checkBoard(col: Int, row: Int): Boolean { val currentIntersection = board[row][col] if (currentIntersection == IntersectionState.Empty) - return null - + return false val isConditionSatisfied = checkAllDirections(col, row, currentIntersection) if (!isConditionSatisfied) - return null + return false return when (currentIntersection) { - IntersectionState.OnBlackStone -> PlayerType.WithBlackStone - IntersectionState.OnWhiteStone -> PlayerType.WithWhiteStone - IntersectionState.Empty -> null + IntersectionState.OnBlackStone -> true + IntersectionState.OnWhiteStone -> true + IntersectionState.Empty -> false } } private fun checkAllDirections( col: Int, row: Int, currentIntersection: IntersectionState ): Boolean { - val directions = arrayOf( - Pair(0, 1), Pair(1, 0), Pair(1, 1), Pair(1, -1), - Pair(-1, 0), Pair(0, -1), Pair(-1, -1), Pair(-1, 1) - ) - for (direction in directions) { val (dRow, dCol) = direction if (checkSingleDirection(col, row, dCol, dRow, currentIntersection)) { From 1d1e89928795d2c930ac10bf08d82fc9a39dbf22 Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 20:01:47 +0900 Subject: [PATCH 19/23] =?UTF-8?q?update:=20UI=20=EC=A0=95=EB=A0=AC=20?= =?UTF-8?q?=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/activity_main.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index dce92a1..be8552c 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,13 +1,14 @@ From e0da51ca1f84ed7a3acc3f645a3c0dce14429920 Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 20:02:16 +0900 Subject: [PATCH 20/23] =?UTF-8?q?update:=20notice=20=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20UI=20=EC=84=B8=EB=B6=80=20=EC=82=AC=ED=95=AD=20?= =?UTF-8?q?=EC=A1=B0=EC=A0=95=20=EB=B0=8F=20=EC=B4=88=EA=B8=B0=20=ED=85=8D?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/activity_main.xml | 7 +++++-- app/src/main/res/values/strings.xml | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index be8552c..19b970f 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1185,6 +1185,9 @@ + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="20dp" + android:text="@string/notice_init" + android:textSize="18sp" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7602a37..4df1419 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,6 +1,7 @@ Omok + 현재는 1번째 차례입니다. 흑돌의 순서입니다. 현재는 %1$d번째 차례입니다. %2$s의 순서입니다. 승자는 %1$s 입니다. From 6152a0d3a44c9f662dea9a454c306c78ef984511 Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 20:03:56 +0900 Subject: [PATCH 21/23] =?UTF-8?q?update:=20=EA=B2=8C=EC=9E=84=20=EC=A2=85?= =?UTF-8?q?=EB=A3=8C=20=EC=8B=9C=20=EC=95=88=EB=82=B4=20=EB=AC=B8=EA=B5=AC?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4df1419..fa4f356 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,5 +3,5 @@ 현재는 1번째 차례입니다. 흑돌의 순서입니다. 현재는 %1$d번째 차례입니다. %2$s의 순서입니다. - 승자는 %1$s 입니다. + 게임 종료! 승자는 %1$s 입니다. From c8e7297945fad27c89a52ff25277952bdab4574b Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 20:08:43 +0900 Subject: [PATCH 22/23] =?UTF-8?q?update:=20PlayerTextAdapter=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/omok/util/PlayerTextAdapter.kt | 13 +++++++++++++ .../main/java/nextstep/omok/view/MainActivity.kt | 5 +++-- 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/nextstep/omok/util/PlayerTextAdapter.kt diff --git a/app/src/main/java/nextstep/omok/util/PlayerTextAdapter.kt b/app/src/main/java/nextstep/omok/util/PlayerTextAdapter.kt new file mode 100644 index 0000000..a6c0495 --- /dev/null +++ b/app/src/main/java/nextstep/omok/util/PlayerTextAdapter.kt @@ -0,0 +1,13 @@ +package nextstep.omok.util + +import nextstep.omok.model.PlayerType + +const val PLAYER_WITH_BLACK_STONE = "흑돌" +const val PLAYER_WITH_WHITE_STONE = "백돌" + +fun adaptPlayerText(currentPlayerType: PlayerType): String { + return when (currentPlayerType) { + PlayerType.WithBlackStone -> PLAYER_WITH_BLACK_STONE + PlayerType.WithWhiteStone -> PLAYER_WITH_WHITE_STONE + } +} \ No newline at end of file diff --git a/app/src/main/java/nextstep/omok/view/MainActivity.kt b/app/src/main/java/nextstep/omok/view/MainActivity.kt index 0c2f7fa..580a3cb 100644 --- a/app/src/main/java/nextstep/omok/view/MainActivity.kt +++ b/app/src/main/java/nextstep/omok/view/MainActivity.kt @@ -12,6 +12,7 @@ import nextstep.omok.R import nextstep.omok.model.OmokModel import nextstep.omok.model.PlayerType import nextstep.omok.presenter.OmokPresenter +import nextstep.omok.util.adaptPlayerText class MainActivity : AppCompatActivity(), OmokContract.OmokView { private lateinit var presenter: OmokContract.OmokPresenter @@ -43,7 +44,7 @@ class MainActivity : AppCompatActivity(), OmokContract.OmokView { } override fun showTurn(currentTurn: Int, currentPlayerType: PlayerType) { - notice.text = getString(R.string.notice_turn, currentTurn, currentPlayerType) + notice.text = getString(R.string.notice_turn, currentTurn, adaptPlayerText(currentPlayerType)) } override fun placeStone(rowIndex: Int, colIndex: Int, playerType: PlayerType) { @@ -64,6 +65,6 @@ class MainActivity : AppCompatActivity(), OmokContract.OmokView { } private fun showWinner(winner: PlayerType) { - notice.text = getString(R.string.notice_winner, winner) + notice.text = getString(R.string.notice_winner, adaptPlayerText(winner)) } } From c39b8f3e194d1041b1313a1d7423c16039501dfc Mon Sep 17 00:00:00 2001 From: HyeonjiJang Date: Fri, 7 Jun 2024 20:13:17 +0900 Subject: [PATCH 23/23] =?UTF-8?q?fix:=20=ED=95=9C=20=EB=B2=88=20=EC=88=98?= =?UTF-8?q?=EB=A5=BC=20=EB=86=93=EC=9D=80=20=EA=B3=B3=EC=97=90=20=EB=8B=A4?= =?UTF-8?q?=EC=8B=9C=20=EB=8F=8C=EC=9D=84=20=EB=86=93=EC=9D=84=20=EC=88=98?= =?UTF-8?q?=20=EC=97=86=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/nextstep/omok/OmokContract.kt | 1 + app/src/main/java/nextstep/omok/model/OmokBoard.kt | 4 ++++ app/src/main/java/nextstep/omok/model/OmokModel.kt | 4 ++++ app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt | 7 +++++-- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/nextstep/omok/OmokContract.kt b/app/src/main/java/nextstep/omok/OmokContract.kt index 3e22984..9cab8b8 100644 --- a/app/src/main/java/nextstep/omok/OmokContract.kt +++ b/app/src/main/java/nextstep/omok/OmokContract.kt @@ -18,6 +18,7 @@ interface OmokContract { /* omokBoard 관련 함수 */ fun updateBoard(rowIndex: Int, colIndex: Int, stone: IntersectionState) + fun getBoardState(rowIndex: Int, colIndex: Int): IntersectionState /* turn 관련 함수 */ fun addTurnCount() diff --git a/app/src/main/java/nextstep/omok/model/OmokBoard.kt b/app/src/main/java/nextstep/omok/model/OmokBoard.kt index bad62b0..af1bcfa 100644 --- a/app/src/main/java/nextstep/omok/model/OmokBoard.kt +++ b/app/src/main/java/nextstep/omok/model/OmokBoard.kt @@ -20,4 +20,8 @@ object OmokBoard { fun getBoard(): List> { return omokBoard } + + fun getBoardIntersection(row: Int, col: Int): IntersectionState { + return omokBoard[row][col] + } } \ No newline at end of file diff --git a/app/src/main/java/nextstep/omok/model/OmokModel.kt b/app/src/main/java/nextstep/omok/model/OmokModel.kt index 2b5259f..76cf318 100644 --- a/app/src/main/java/nextstep/omok/model/OmokModel.kt +++ b/app/src/main/java/nextstep/omok/model/OmokModel.kt @@ -25,6 +25,10 @@ class OmokModel : OmokContract.OmokModel { omokBoard.updateBoard(rowIndex, colIndex, stone) } + override fun getBoardState(rowIndex: Int, colIndex: Int): IntersectionState { + return omokBoard.getBoardIntersection(rowIndex, colIndex) + } + /* turn 관련 함수 */ override fun addTurnCount() { diff --git a/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt b/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt index 98c34cb..f56f638 100644 --- a/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt +++ b/app/src/main/java/nextstep/omok/presenter/OmokPresenter.kt @@ -2,14 +2,17 @@ package nextstep.omok.presenter import nextstep.omok.OmokContract import nextstep.omok.model.GameState +import nextstep.omok.model.IntersectionState class OmokPresenter( private var activity: OmokContract.OmokView, private var model: OmokContract.OmokModel ) : OmokContract.OmokPresenter { override fun onIntersectionClick(rowIndex: Int, colIndex: Int) { - updateBoard(rowIndex, colIndex) - checkWinnerExist() + if (model.getBoardState(rowIndex, colIndex) == IntersectionState.Empty) { + updateBoard(rowIndex, colIndex) + checkWinnerExist() + } } private fun updateBoard(rowIndex: Int, colIndex: Int) {