Skip to content

Commit

Permalink
Merge pull request #13 from nwagu/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
nwagu authored Jun 7, 2021
2 parents b7430b1 + 3b5f992 commit 6a2618e
Show file tree
Hide file tree
Showing 67 changed files with 8,038 additions and 341 deletions.
1 change: 1 addition & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions androidApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ android {
applicationId = "com.nwagu.android.chessboy"
minSdk = 21
targetSdk = 30
versionCode = 10
versionName = "3.0.0"
versionCode = 11
versionName = "3.1.0"
}
buildTypes {
getByName("release") {
Expand All @@ -41,11 +41,12 @@ android {
dependencies {
implementation(project(":bluetoothchat"))
implementation(project(":chess"))
implementation(project(":jwtc"))
implementation(project(":chessengineintegration"))

implementation("com.google.android.material:material:1.3.0")
implementation("androidx.appcompat:appcompat:1.3.0")
implementation("androidx.constraintlayout:constraintlayout:2.0.4")

implementation("androidx.activity:activity-compose:1.3.0-alpha08")
implementation("androidx.fragment:fragment-ktx:1.3.4")

Expand All @@ -64,5 +65,6 @@ dependencies {
implementation("com.google.firebase:firebase-database-ktx")

implementation("com.karumi:dexter:6.2.2")
implementation("com.jakewharton.timber:timber:4.7.1")

}
1 change: 1 addition & 0 deletions androidApp/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
android:label="@string/app_name"
android:allowBackup="false"
android:supportsRtl="true"
android:extractNativeLibs="true"
android:theme="@style/AppTheme">

<activity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ sealed class BluetoothMessage {
override val value: String
get() {
return when(move) {
is Castling -> "MOVE-CASTLING-${move.source}-${move.destination}-${move.secondarySource}-${move.secondaryDestination}"
is Castling -> "MOVE-CASTLING-${move.source}-${move.destination}"
is EnPassant -> "MOVE-ENPASSANT-${move.source}-${move.destination}"
is Promotion -> "MOVE-PROMOTION-${move.source}-${move.destination}-${move.promotionType.name}"
is RegularMove -> "MOVE-REGULAR-${move.source}-${move.destination}"
Expand Down Expand Up @@ -92,9 +92,7 @@ fun parseMessage(message: String): BluetoothMessage? {
return BluetoothMessage.MoveMessage(
Castling(
source = messageSplit[2].toInt(),
destination = messageSplit[3].toInt(),
secondarySource = messageSplit[4].toInt(),
secondaryDestination = messageSplit[5].toInt()))
destination = messageSplit[3].toInt()))
}
"PROMOTION" -> {
return BluetoothMessage.MoveMessage(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.nwagu.android.chessboy.players

import com.nwagu.chess.board.Board
import com.nwagu.chess.board.squaresWithPiecesColored
import com.nwagu.chess.board.turn
import com.nwagu.chess.moves.Move
import com.nwagu.chess.moves.getPossibleMovesFrom

class GrandPa : MoveGenerator {

override val id = PlayersRegister.GRANDPA.id
override val name = "GrandPa"

override suspend fun getNextMove(board: Board): Move? {

val moves = mutableListOf<Move>()

board.squaresWithPiecesColored(board.turn).forEach {
moves.addAll(board.getPossibleMovesFrom(it))
}

// TODO return a decent choice of move
return moves.randomOrNull()

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.nwagu.android.chessboy.players

import com.nwagu.chess.board.Board
import com.nwagu.chess.convention.getFen
import com.nwagu.chess.enums.ChessPieceType
import com.nwagu.chess.moves.*
import jwtc.chess.BoardConstants
import jwtc.chess.JNI
import jwtc.chess.Move.*

class JWTC: AI {

override val id = PlayersRegister.JWTC.id
override val name = "JWTC"
override var level = 5

lateinit var jni: JNI

override fun init() {
jni = JNI()
}

override suspend fun getNextMove(board: Board): Move? {

jni.newGame()
jni.initFEN(board.getFen())
jni.searchDepth(level)

val move = jni.move

if (move == 0)
return null

val source: Int = getFrom(move)
val destination: Int = getTo(move)

if (isPromotionMove(move)) {
val promotionPieceType = when (getPromotionPiece(move)) {
BoardConstants.QUEEN -> ChessPieceType.QUEEN
BoardConstants.KNIGHT -> ChessPieceType.KNIGHT
BoardConstants.ROOK -> ChessPieceType.ROOK
BoardConstants.BISHOP -> ChessPieceType.BISHOP
else -> throw IllegalStateException("Invalid Promotion Piece!")
}
return Promotion(source, destination, promotionPieceType)
}

if (isEP(move)) {
return EnPassant(source, destination)
}

if (isOOO(move)) {
return Castling(source, destination)
}

if (isOO(move)) {
return Castling(source, destination)
}

return RegularMove(source, destination)

}

}
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
package com.nwagu.android.chessboy.movesgenerators
package com.nwagu.android.chessboy.players

import com.nwagu.android.chessboy.widgets.SelectableOpponent
import com.nwagu.chess.Player
import com.nwagu.chess.board.Board
import com.nwagu.chess.enums.Level
import com.nwagu.chess.moves.Move

object User: Player {
override val id = PlayersRegister.USER.id
override val name = "You"
override val level = Level.INDETERMINATE
}

data class BluetoothOpponent(
override val name: String = "Bluetooth Opponent",
val address: String?,
override val level: Level = Level.INDETERMINATE
): Player, SelectableOpponent {
val address: String,
override val id: String = "${PlayersRegister.BLUETOOTH.id}-${address}"
): SelectableOpponent

override val displayName = name
override var selected = false
}

interface AI: Player, SelectableOpponent {
interface MoveGenerator: SelectableOpponent {
override val name: String
override val level: Level
suspend fun getNextMove(board: Board): Move?
}

interface AI: MoveGenerator {
var level: Int
fun init()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.nwagu.android.chessboy.players

enum class PlayersRegister(val id: String) {
USER(User::class.java.simpleName),
GRANDPA(GrandPa::class.java.simpleName),
RANDOM(RandomMoveGenerator::class.java.simpleName),
JWTC(com.nwagu.android.chessboy.players.JWTC::class.java.simpleName),
BLUETOOTH(BluetoothOpponent::class.java.simpleName),
UCI(UCIChessEngine::class.java.simpleName)
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
package com.nwagu.android.chessboy.movesgenerators
package com.nwagu.android.chessboy.players

import com.nwagu.android.chessboy.widgets.SelectableOpponent
import com.nwagu.chess.board.Board
import com.nwagu.chess.board.squaresWithPiecesColored
import com.nwagu.chess.board.turn
import com.nwagu.chess.enums.Level
import com.nwagu.chess.moves.Move
import com.nwagu.chess.moves.getPossibleMovesFrom

class RandomMoveGenerator : AI, SelectableOpponent {
class RandomMoveGenerator : MoveGenerator {

override val id = PlayersRegister.RANDOM.id
override val name = "Zero Intelligence"
override val level = Level.ZERO

override suspend fun getNextMove(board: Board): Move? {

Expand All @@ -24,7 +22,4 @@ class RandomMoveGenerator : AI, SelectableOpponent {
return moves.randomOrNull()

}

override val displayName = name
override var selected = false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.nwagu.android.chessboy.players

import com.nwagu.chess.board.Board
import com.nwagu.chess.convention.convertChessEngineMoveToMove
import com.nwagu.chess.convention.getFen
import com.nwagu.chess.moves.Move
import com.nwagu.chessengineintegration.UCIBridge
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import timber.log.Timber

class UCIChessEngine(
override val name: String,
val pathToBinary: String
): AI {

override val id = "${PlayersRegister.UCI.id}-${pathToBinary}"
override var level: Int = 5

lateinit var uciBridge: UCIBridge

private val chessEngineMove = MutableStateFlow("")

override fun init() {

uciBridge = UCIBridge(pathToBinary, object : UCIBridge.UCIEngineListener {
override fun onUciOk() {
Timber.i("UCI OK")
}

override fun onReady() {
Timber.i("UCI Ready")
}

override fun onBestMove(move: String) {
Timber.i(move)
chessEngineMove.value = move
}

override fun onCopyProtection() {
Timber.i("copy protection")
}

override fun onId(id: Pair<String, String>) {
Timber.i("ID received: ${id.first} = ${id.second}")
}

override fun onInfo(info: String) {
Timber.i("INFO received: ${info}")
}

override fun onOption(option: Pair<String, String>) {
Timber.i("Option received: ${option.first} = ${option.second}")
}

override fun onError(error: String) {
Timber.e(error)
}

})

uciBridge.init()
}

override suspend fun getNextMove(board: Board): Move? {

var move: String? = null

val job = GlobalScope.launch {
chessEngineMove.collect {
move = it
}
}

uciBridge.play(board.getFen(), level)

while (move == null) {
//
}

job.cancel()

return board.convertChessEngineMoveToMove(move ?: "")

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,14 @@ fun GameViewPortrait(
dialogController: DialogController
) {

val gameChanged by viewModel.gameUpdated.collectAsState(0)

Column(
modifier = Modifier.verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.Center
) {

// Invisible text to force recompose on game changed
Text(text = gameChanged.toString(), Modifier.size(0.dp))
PlayerDisplay(modifier = Modifier, viewModel, viewModel.game.colorOnUserSideOfBoard.opposite())
// CaptivesView(modifier = Modifier.fillMaxWidth(), viewModel, viewModel.game.colorOnUserSideOfBoard)
ChessBoardView(modifier = Modifier.fillMaxWidth(), viewModel)
Expand All @@ -159,6 +162,8 @@ fun GameViewLandscape(
dialogController: DialogController
) {

val gameChanged by viewModel.gameUpdated.collectAsState(0)

Row(modifier = Modifier
.fillMaxWidth()
.horizontalScroll(rememberScrollState())) {
Expand All @@ -169,6 +174,8 @@ fun GameViewLandscape(
.verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.Center
) {
// Invisible text to force recompose on game changed
Text(text = gameChanged.toString(), Modifier.size(0.dp))
PlayerDisplay(
modifier = Modifier,
viewModel, viewModel.game.colorOnUserSideOfBoard.opposite())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import com.nwagu.android.chessboy.BluetoothController
import com.nwagu.android.chessboy.MainActivity
import com.nwagu.android.chessboy.dialogs.DialogController
import com.nwagu.android.chessboy.model.data.ScreenConfig
import com.nwagu.android.chessboy.movesgenerators.BluetoothOpponent
import com.nwagu.android.chessboy.players.BluetoothOpponent
import com.nwagu.android.chessboy.ui.AppColor
import com.nwagu.android.chessboy.vm.GameViewModel
import com.nwagu.android.chessboy.vm.NewBluetoothGameViewModel
Expand Down Expand Up @@ -177,15 +177,12 @@ fun NewBluetoothGameView(
when (selectedColor) {
ChessPieceColor.WHITE -> {
selectedDevice?.let {
gameViewModel.startNewBluetoothGame(
true,
it.address
)
gameViewModel.attemptConnectToDevice(it.address)
}
}
ChessPieceColor.BLACK -> {
bluetoothController.ensureDiscoverable()
gameViewModel.startNewBluetoothGame(false, null)
gameViewModel.listenForConnection()
}
}

Expand Down
Loading

0 comments on commit 6a2618e

Please sign in to comment.