Skip to content
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

[충남대 Android_정기주] 미션 제출합니다. #41

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,16 @@
# android-omok-precourse
# android-omok-precourse

-KakaoTechCampus Step1 2차 미니과제
-안드로이드 프레임워크를 사용하여 모바일 앱으로 오목을 구현한다.

#기능 목록
1. 오목판 초기화
- 오목판을 비워져있도록 구성한다.
2. 돌 놓기 기능
- 사용자는 오목판을 클릭하여 돌을 놓을 수 있다.
- 흑돌과 백돌이 번갈아가면서 돌을 놓도록 한다.
3. 승리 여부 확인 기능
- 가로나 세로, 대각선으로 다섯 개의 연속된 돌이 있는 확인한다.
- 렌주 룰과 같은 복잡한 룰을 고려하지 않고, 6목 이상의 장목도 승리 조건으로 인정한다.
4. 무승부 기능
- 판을 전부 돌로 채웠어도 승부가 결정나지 않으면 무승부로 처리한다.
123 changes: 123 additions & 0 deletions app/src/androidTest/java/nextstep/omok/MainActivityTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package nextstep.omok

import androidx.test.core.app.ActivityScenario
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
import android.widget.ImageView
import android.widget.TableLayout
import android.widget.TableRow
import android.widget.TextView
import androidx.core.view.children
class MainActivityTest {
private lateinit var activity: MainActivity

@Test
fun testStonePlacement() {
ActivityScenario.launch(MainActivity::class.java).onActivity {
activity = it

val board = activity.findViewById<TableLayout>(R.id.board)
val firstCell = board
.children
.filterIsInstance<TableRow>()
.flatMap { it.children }
.filterIsInstance<ImageView>()
.first()

firstCell.performClick()

val row = 0
val col = 0
val expectedDrawable = R.drawable.black_stone

assertThat(firstCell.drawable).isNotNull
assertThat((firstCell.drawable.constantState)).isEqualTo(activity.getDrawable(expectedDrawable)!!.constantState)
assertThat(activity.boardState[row][col]).isEqualTo("black")
}
}

@Test
fun testFiveVictory() {
ActivityScenario.launch(MainActivity::class.java).onActivity {
activity = it

val board = activity.findViewById<TableLayout>(R.id.board)
val cells = board
.children
.filterIsInstance<TableRow>()
.flatMap { it.children }
.filterIsInstance<ImageView>()
.toList()

for (i in 0 until 5) {
val cell = cells[i]
cell.performClick()
if (i < 4) {
activity.changePlayer()
}
}

val showWinner = activity.findViewById<TextView>(R.id.showWinner)

assertThat(showWinner.text.toString()).isEqualTo("흑돌 승리!")
assertThat(activity.winnerPlayer).isEqualTo("black")
assertThat(activity.gameOver).isTrue
}
}
@Test
fun testFiveVictory2() {
ActivityScenario.launch(MainActivity::class.java).onActivity {
activity = it

val board = activity.findViewById<TableLayout>(R.id.board)
val cells = board
.children
.filterIsInstance<TableRow>()
.flatMap { it.children }
.filterIsInstance<ImageView>()
.toList()

for (i in 0 until 5) {
val cell = cells[i * (activity.boardSize + 1)]
cell.performClick()
if (i < 4) {
activity.changePlayer()
}
}

val showWinner = activity.findViewById<TextView>(R.id.showWinner)

assertThat(showWinner.text.toString()).isEqualTo("흑돌 승리!")
assertThat(activity.winnerPlayer).isEqualTo("black")
assertThat(activity.gameOver).isTrue
}
}
@Test
fun testFiveVictory3() {
ActivityScenario.launch(MainActivity::class.java).onActivity {
activity = it

val board = activity.findViewById<TableLayout>(R.id.board)
val cells = board
.children
.filterIsInstance<TableRow>()
.flatMap { it.children }
.filterIsInstance<ImageView>()
.toList()

for (i in 0 until 5) {
val cell = cells[(i + 1) * (activity.boardSize - 1)]
cell.performClick()
if (i < 4) {
activity.changePlayer()
}
}

val showWinner = activity.findViewById<TextView>(R.id.showWinner)

assertThat(showWinner.text.toString()).isEqualTo("흑돌 승리!")
assertThat(activity.winnerPlayer).isEqualTo("black")
assertThat(activity.gameOver).isTrue
}
}
}
98 changes: 97 additions & 1 deletion app/src/main/java/nextstep/omok/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,21 @@ 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

val derivative = arrayOf(
arrayOf(1, 0), arrayOf(0, 1), arrayOf(1, 1), arrayOf(1, -1)
)

class MainActivity : AppCompatActivity() {
val boardSize: Int = 15
var player: String = "black"
var winnerPlayer: String = ""
var gameOver: Boolean = false
var boardState = Array(boardSize) { Array(boardSize) { "" } }

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Expand All @@ -18,6 +29,91 @@ class MainActivity : AppCompatActivity() {
.filterIsInstance<TableRow>()
.flatMap { it.children }
.filterIsInstance<ImageView>()
.forEach { view -> view.setOnClickListener { view.setImageResource(R.drawable.black_stone) } }
.forEachIndexed { index, view ->
view.setOnClickListener { onCellClicked(index, view) }
}

}

fun onCellClicked(index: Int, view: ImageView) {
if (gameOver) {
return
}

val row: Int = index / boardSize
val col: Int = index % boardSize
if (boardState[row][col] == "") {
placeStone(view)
boardState[row][col] = player
if (checkGameSet(row, col)) {
winnerPlayer = player
showWinner()
} else if (isBoardFull()) {
showDraw()
} else {
changePlayer()
}
}
}

fun placeStone(view: ImageView) {
if (player == "black") {
view.setImageResource(R.drawable.black_stone)
} else {
view.setImageResource(R.drawable.white_stone)
}
}

fun checkGameSet(row: Int, col: Int): Boolean {
for (direction in derivative) {
var count = 1

count += countStones(row, col, direction[0], direction[1])
count += countStones(row, col, -direction[0], -direction[1])

if (count >= 5) {
return true
}
}
return false
}

fun countStones(row: Int, col: Int, rowDir: Int, colDir: Int): Int {
var currentRow = row + rowDir
var currentCol = col + colDir
var count = 0

while (currentRow in 0 until boardSize && currentCol in 0 until boardSize && boardState[currentRow][currentCol] == player) {
count++
currentRow += rowDir
currentCol += colDir
}
return count
}

fun changePlayer() {
player = if (player == "black") "white" else "black"
}

fun showWinner() {
val showWinner = findViewById<TextView>(R.id.showWinner)
showWinner.text = if (winnerPlayer == "black") "흑돌 승리!" else "백돌 승리!"
gameOver = true
}
fun showDraw() {
val showWinner = findViewById<TextView>(R.id.showWinner)
showWinner.text = "무승부!"
gameOver = true
}

fun isBoardFull(): Boolean {
for (row in boardState) {
for (cell in row) {
if (cell == "") {
return false
}
}
}
return true
}
}
8 changes: 8 additions & 0 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1179,5 +1179,13 @@
android:background="@drawable/board_bottom_right" />
</TableRow>

<TextView
android:id="@+id/showWinner"
android:layout_width="100dp"
android:layout_height="70dp"
android:gravity="center"
android:textColor="@color/black"
android:textSize="30dp" />

</TableLayout>
</LinearLayout>