-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* rebase: step2 * feat: set up the android project * feat: domain 이동 * feat: add main activity and resources * refactor(Omok, Controller): run 함수 삭제 및 컨트롤러로 이동 * feat(activity_main): TextView 추가 * feat(GameEventListener): GameEventListener 구현 * refactor(Omok): 필요없는 주석 삭제 * feat(Listener): 이벤트 리스너 구현 및 strings.xml에 string 정의 * feat(MainActivity): MainActivity 구현 * refactor(Activity, Listener): 패키지 이동 * refactor(Omok): endGame 함수 수정 * refactor(OmokTest): OmokTest 테스트 재구현 * refactor(InputView, OutputView): InputView OutputView 인터페이스 삭제 * refactor(TurnResult): TurnResult 생성, 점진적인 리팩터링 * refactor(MainActivity, PlayersTest): 필요없는 테스트 삭제, 도메인 변경에 따른 MainActivity 변경 * refactor(Players, Omok, Controller): Players 위치 Omok 안으로 변경, 안드로이드 TurnEventListener 삭제 * refactor(MainActivity, GameEventListener): 버그 수정 * refactor(OmokTest, PlayersTest): 리팩터링에 따른 테스트 수정 * feat(MainActivity, Omok, OmokConstract, OmokDBHelper, Players): 데이터베이스를 이용한 오목판 저장 * refactor(gitignore): gitignore 추가 * feat(DBManager): DB로부터 원하는 정보를 뽑아주는 DBManager 생성 * refactor(MainActivity): 메인 액티비티 리팩터링 * refactor(OmokDBManager): 필요없는 코드 삭제 * refactor(xml): 오목판 커스텀 * refactor(MainActivity): 오목판 세팅 함수 분리 * refactor(MainActivity): 필요없는 코드 삭제 * fix(WhitePlayerTest): 테스트 코드 수정 * refactor(xml): 필요없는 파일 삭제 * refactor(Players, Player): 놓은 돌의 개수를 반환하는 함수 작성 * refactor(PlayerState): points 변수 protected 삭제 * refactor(PlayerState): points 변수 protected 복구, getAllPoints 깊은 복사 * refactor(Black,WhitePlayerTest): 필요없는 정보 숨기기 * refactor(Points): Point List 깊은 복사 * refactor(PlayersTest): 테스트 코드 수정 * refactor(MainActivity): 코드 다이어트 및 by lazy 적용 * refactor(all): ktlintFormatting * refactor(Players): latestPlayer 불변으로 변경 * refactor(Players, WhitePlayer, BlackPlayer): stone -> point로 명칭 변경, 최근 플레이어를 구하는 책임 이동 * refactor(OmokGameEventListener): InputView의 인터페이스 삭제, GameEventListener을 TurnEventListener로 명칭 변경 * fix(BlackPlayer, WhitePlayer): 오류 수정 * refactor(TurnResult): 턴의 결과를 모두 포함하도록 수정 * refactor(Omok): 필요없는 함수 삭제 * refactor(MainActivity, TurnEventListener): 도메인 변경에 따른 코드 변경 * refactor(Players, MainActivity): 필요없는 코드 삭제, 변수 네이밍 변경 * refactor(MainActivity, Controller, DBHelper, OutputView): 리스너, DB매니저 삭제, 뷰 설정 코드 메인 액티비티로 이동, DBHelper에 함수 추가 * refactor(ktlintFormat): ktlintformatting * refactor(DBHelper): db를 변수로 가지도록 변경 * refactor(Players): Players 팩토리 함수 생성 * refactor(MainActivity): applicationContext -> this 변경 * refactor(MainActivity): 많은 if문 when문 사용하여 정리 * refactor(PlayersTest): 팩토리 함수 구현으로 인한 변경 * refactor(OmokDBHelper): 오목 도메인을 가질 수 있도록 수정 * refactor(MainActivity): onCreate에서 onClickListener 내용 분리 --------- Co-authored-by: woowahan-pjs <[email protected]>
- Loading branch information
1 parent
5ccb0b3
commit 50e7c2f
Showing
101 changed files
with
3,760 additions
and
58 deletions.
There are no files selected for viewing
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 |
---|---|---|
@@ -1,32 +1,33 @@ | ||
HELP.md | ||
.gradle | ||
# Gradle files | ||
.gradle/ | ||
build/ | ||
!gradle/wrapper/gradle-wrapper.jar | ||
!**/src/main/** | ||
!**/src/test/** | ||
|
||
### STS ### | ||
.apt_generated | ||
.classpath | ||
.factorypath | ||
.project | ||
.settings | ||
.springBeans | ||
.sts4-cache | ||
# Local configuration file (sdk path, etc) | ||
local.properties | ||
|
||
### IntelliJ IDEA ### | ||
.idea | ||
*.iws | ||
# Log/OS Files | ||
*.log | ||
|
||
# Android Studio generated files and folders | ||
captures/ | ||
.externalNativeBuild/ | ||
.cxx/ | ||
*.apk | ||
output.json | ||
|
||
# IntelliJ | ||
*.iml | ||
*.ipr | ||
out/ | ||
.idea/ | ||
misc.xml | ||
deploymentTargetDropDown.xml | ||
render.experimental.xml | ||
|
||
# Keystore files | ||
*.jks | ||
*.keystore | ||
|
||
### NetBeans ### | ||
/nbproject/private/ | ||
/nbbuild/ | ||
/dist/ | ||
/nbdist/ | ||
/.nb-gradle/ | ||
# Google Services (e.g. APIs or Firebase) | ||
google-services.json | ||
|
||
### VS Code ### | ||
.vscode/ | ||
# Android Profiling | ||
*.hprof |
Binary file not shown.
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 @@ | ||
/build |
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,47 @@ | ||
plugins { | ||
id("com.android.application") | ||
id("org.jetbrains.kotlin.android") | ||
} | ||
|
||
android { | ||
namespace = "woowacourse.omok" | ||
compileSdk = 33 | ||
|
||
defaultConfig { | ||
applicationId = "woowacourse.omok" | ||
minSdk = 26 | ||
targetSdk = 33 | ||
versionCode = 1 | ||
versionName = "1.0" | ||
|
||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" | ||
} | ||
|
||
buildTypes { | ||
getByName("release") { | ||
isMinifyEnabled = false | ||
proguardFiles( | ||
getDefaultProguardFile("proguard-android-optimize.txt"), | ||
"proguard-rules.pro" | ||
) | ||
} | ||
} | ||
compileOptions { | ||
sourceCompatibility = JavaVersion.VERSION_11 | ||
targetCompatibility = JavaVersion.VERSION_11 | ||
} | ||
kotlinOptions { | ||
jvmTarget = "11" | ||
} | ||
} | ||
|
||
dependencies { | ||
implementation(project(":domain")) | ||
implementation("androidx.core:core-ktx:1.9.0") | ||
implementation("androidx.appcompat:appcompat:1.6.0") | ||
implementation("com.google.android.material:material:1.7.0") | ||
implementation("androidx.constraintlayout:constraintlayout:2.1.4") | ||
testImplementation("junit:junit:4.13.2") | ||
androidTestImplementation("androidx.test.ext:junit:1.1.5") | ||
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") | ||
} |
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,21 @@ | ||
# Add project specific ProGuard rules here. | ||
# You can control the set of applied configuration files using the | ||
# proguardFiles setting in build.gradle. | ||
# | ||
# For more details, see | ||
# http:https://developer.android.com/guide/developing/tools/proguard.html | ||
|
||
# If your project uses WebView with JS, uncomment the following | ||
# and specify the fully qualified class name to the JavaScript interface | ||
# class: | ||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
# public *; | ||
#} | ||
|
||
# Uncomment this to preserve the line number information for | ||
# debugging stack traces. | ||
#-keepattributes SourceFile,LineNumberTable | ||
|
||
# If you keep the line number information, uncomment this to | ||
# hide the original source file name. | ||
#-renamesourcefileattribute SourceFile |
Binary file not shown.
Empty file.
Binary file not shown.
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,23 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http:https://schemas.android.com/apk/res/android" | ||
xmlns:tools="http:https://schemas.android.com/tools"> | ||
|
||
<application | ||
android:allowBackup="true" | ||
android:icon="@mipmap/ic_launcher" | ||
android:label="@string/app_name" | ||
android:supportsRtl="true" | ||
android:theme="@style/Theme.Oomok" | ||
tools:targetApi="31"> | ||
<activity | ||
android:name=".activity.MainActivity" | ||
android:exported="true"> | ||
<intent-filter> | ||
<action android:name="android.intent.action.MAIN" /> | ||
|
||
<category android:name="android.intent.category.LAUNCHER" /> | ||
</intent-filter> | ||
</activity> | ||
</application> | ||
|
||
</manifest> |
123 changes: 123 additions & 0 deletions
123
app/src/main/java/woowacourse/omok/activity/MainActivity.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,123 @@ | ||
package woowacourse.omok.activity | ||
|
||
import android.os.Bundle | ||
import android.widget.ImageView | ||
import android.widget.TableLayout | ||
import android.widget.TableRow | ||
import android.widget.TextView | ||
import android.widget.Toast | ||
import androidx.appcompat.app.AppCompatActivity | ||
import androidx.core.view.children | ||
import domain.game.Omok | ||
import domain.game.Omok.Companion.OMOK_BOARD_SIZE | ||
import domain.player.BlackPlayer | ||
import domain.player.WhitePlayer | ||
import domain.point.Point | ||
import domain.point.Points | ||
import domain.result.TurnResult | ||
import domain.rule.BlackRenjuRule | ||
import domain.rule.WhiteRenjuRule | ||
import domain.state.PlayingState | ||
import domain.stone.StoneColor | ||
import view.mapper.toPresentation | ||
import woowacourse.omok.R | ||
import woowacourse.omok.db.OmokDBHelper | ||
|
||
class MainActivity : AppCompatActivity() { | ||
private val boards: List<ImageView> by lazy { getBoardViews() } | ||
private val descriptionView: TextView by lazy { findViewById(R.id.description) } | ||
private val dbHelper: OmokDBHelper by lazy { OmokDBHelper(this) } | ||
private val omok: Omok by lazy { initOmok() } | ||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
setContentView(R.layout.activity_main) | ||
|
||
onStartGame() | ||
onStartTurn(omok.players.curPlayerColor) | ||
var result: TurnResult = TurnResult.Playing(false, omok.players) | ||
|
||
boards.forEachIndexed { index, view -> | ||
view.setOnClickListener { result = onClick(result, index, view) } | ||
} | ||
} | ||
|
||
override fun onStop() { | ||
super.onStop() | ||
if (!omok.players.isPlaying) dbHelper.deleteAll() | ||
} | ||
|
||
override fun onDestroy() { | ||
super.onDestroy() | ||
dbHelper.close() | ||
} | ||
|
||
private fun initOmok(): Omok { | ||
val blackIndexs = dbHelper.getIndexsByColor(StoneColor.BLACK) | ||
val whiteIndexs = dbHelper.getIndexsByColor(StoneColor.WHITE) | ||
|
||
blackIndexs.forEach { | ||
setStone(boards[it], StoneColor.BLACK) | ||
} | ||
whiteIndexs.forEach { | ||
setStone(boards[it], StoneColor.WHITE) | ||
} | ||
|
||
val blackPlayer = BlackPlayer(PlayingState(indexsToPoints(blackIndexs)), rule = BlackRenjuRule()) | ||
val whitePlayer = WhitePlayer(PlayingState(indexsToPoints(whiteIndexs)), rule = WhiteRenjuRule()) | ||
return Omok(blackPlayer, whitePlayer) | ||
} | ||
|
||
private fun onStartGame() { | ||
Toast.makeText(this, R.string.start_game, Toast.LENGTH_LONG).show() | ||
} | ||
|
||
private fun onClick(result: TurnResult, index: Int, view: ImageView): TurnResult { | ||
if (result !is TurnResult.Playing) return result | ||
val nextResult = omok.takeTurn(calculateIndexToPoint(index)) | ||
onEndTurn(view, index, nextResult) | ||
onEndGame(nextResult) | ||
return nextResult | ||
} | ||
|
||
private fun onEndGame(result: TurnResult) { | ||
val descriptionView = findViewById<TextView>(R.id.description) | ||
when (result) { | ||
is TurnResult.Playing -> return | ||
is TurnResult.Foul -> descriptionView.text = this.getString(R.string.is_forbidden).plus(this.getString(R.string.who_is_winner).format(result.winColor.toPresentation().text)) | ||
is TurnResult.Win -> descriptionView.text = this.getString(R.string.who_is_winner).format(result.winColor.toPresentation().text) | ||
} | ||
Toast.makeText(this, R.string.end_game, Toast.LENGTH_LONG).show() | ||
} | ||
|
||
private fun onStartTurn(stoneColor: StoneColor) { | ||
descriptionView.text = this.getString(R.string.who_is_turn).format(stoneColor.toPresentation().text) | ||
} | ||
|
||
private fun setStone(view: ImageView, color: StoneColor) { | ||
when (color) { | ||
StoneColor.BLACK -> view.setImageResource(R.drawable.pink_bear) | ||
StoneColor.WHITE -> view.setImageResource(R.drawable.white_bear) | ||
} | ||
} | ||
|
||
private fun onEndTurn(view: ImageView, index: Int, result: TurnResult) { | ||
if (result is TurnResult.Playing && result.isExistPoint) Toast.makeText(this, R.string.already_exist, Toast.LENGTH_LONG).show() | ||
if (result !is TurnResult.Playing || !result.isExistPoint) { | ||
setStone(view, omok.players.curPlayerColor.next()) | ||
dbHelper.insert(index, omok.players.curPlayerColor.next()) | ||
} | ||
descriptionView.text = this.getString(R.string.who_is_turn).format(result.players.curPlayerColor.toPresentation().text) | ||
} | ||
|
||
private fun getBoardViews(): List<ImageView> = findViewById<TableLayout>(R.id.board) | ||
.children | ||
.filterIsInstance<TableRow>() | ||
.flatMap { it.children } | ||
.filterIsInstance<ImageView>().toList() | ||
|
||
private fun calculateIndexToPoint(index: Int): Point = | ||
Point(index / OMOK_BOARD_SIZE + 1, index % OMOK_BOARD_SIZE + 1) | ||
|
||
private fun indexsToPoints(indexs: List<Int>): Points = | ||
Points(indexs.map { calculateIndexToPoint(it) }) | ||
} |
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,9 @@ | ||
package woowacourse.omok.db | ||
|
||
import android.provider.BaseColumns | ||
|
||
object OmokConstract : BaseColumns { | ||
const val TABLE_NAME = "game_info" | ||
const val TABLE_COLUMN_POSITION = "position" | ||
const val TABLE_COLUMN_COLOR = "color" | ||
} |
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,61 @@ | ||
package woowacourse.omok.db | ||
|
||
import android.content.ContentValues | ||
import android.content.Context | ||
import android.database.sqlite.SQLiteDatabase | ||
import android.database.sqlite.SQLiteOpenHelper | ||
import domain.stone.StoneColor | ||
|
||
class OmokDBHelper(context: Context?) : SQLiteOpenHelper(context, DATABASE_NAME, null, 1) { | ||
private val db = writableDatabase | ||
override fun onCreate(db: SQLiteDatabase?) { | ||
db?.execSQL( | ||
"CREATE TABLE ${OmokConstract.TABLE_NAME} (" + | ||
" ${OmokConstract.TABLE_COLUMN_POSITION} int not null," + | ||
" ${OmokConstract.TABLE_COLUMN_COLOR} varchar(50) not null" + | ||
");" | ||
) | ||
} | ||
|
||
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) { | ||
db?.execSQL("DROP TABLE IF EXISTS ${OmokConstract.TABLE_NAME}") | ||
onCreate(db) | ||
} | ||
|
||
fun getIndexsByColor(color: StoneColor): List<Int> { | ||
val indexs = mutableListOf<Int>() | ||
if (!db.isOpen) throw IllegalAccessException() | ||
val cursor = db.query( | ||
OmokConstract.TABLE_NAME, | ||
arrayOf(OmokConstract.TABLE_COLUMN_POSITION), | ||
"${OmokConstract.TABLE_COLUMN_COLOR} = ?", | ||
arrayOf(color.name), | ||
null, | ||
null, | ||
null | ||
) | ||
|
||
while (cursor.moveToNext()) indexs.add(cursor.getInt(0)) | ||
return indexs.toList() | ||
} | ||
|
||
fun insert(index: Int, color: StoneColor) { | ||
if (!db.isOpen) throw IllegalAccessException() | ||
db.insert(OmokConstract.TABLE_NAME, null, values(index, color)) | ||
} | ||
|
||
private fun values(position: Int, color: StoneColor): ContentValues { | ||
val values = ContentValues() | ||
values.put(OmokConstract.TABLE_COLUMN_POSITION, position) | ||
values.put(OmokConstract.TABLE_COLUMN_COLOR, color.name) | ||
return values | ||
} | ||
|
||
fun deleteAll() { | ||
db.execSQL("DELETE FROM ${OmokConstract.TABLE_NAME}") | ||
} | ||
|
||
companion object { | ||
private val DATABASE_NAME = "omok" | ||
} | ||
} |
Binary file not shown.
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,30 @@ | ||
<vector xmlns:android="http:https://schemas.android.com/apk/res/android" | ||
xmlns:aapt="http:https://schemas.android.com/aapt" | ||
android:width="108dp" | ||
android:height="108dp" | ||
android:viewportWidth="108" | ||
android:viewportHeight="108"> | ||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z"> | ||
<aapt:attr name="android:fillColor"> | ||
<gradient | ||
android:endX="85.84757" | ||
android:endY="92.4963" | ||
android:startX="42.9492" | ||
android:startY="49.59793" | ||
android:type="linear"> | ||
<item | ||
android:color="#44000000" | ||
android:offset="0.0" /> | ||
<item | ||
android:color="#00000000" | ||
android:offset="1.0" /> | ||
</gradient> | ||
</aapt:attr> | ||
</path> | ||
<path | ||
android:fillColor="#FFFFFF" | ||
android:fillType="nonZero" | ||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z" | ||
android:strokeWidth="1" | ||
android:strokeColor="#00000000" /> | ||
</vector> |
Binary file not shown.
Oops, something went wrong.