Skip to content

Commit

Permalink
部分模型改为value class
Browse files Browse the repository at this point in the history
  • Loading branch information
ssttkkl committed Sep 30, 2024
1 parent d6ce11d commit d1c29b3
Show file tree
Hide file tree
Showing 13 changed files with 272 additions and 322 deletions.
8 changes: 4 additions & 4 deletions mahjong-utils-entry/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,16 @@ kotlin {
}
if (enableWasm) {
val wasmJsMain by getting {
dependsOn(nonJsMain)
dependsOn(wasmMain)
}
val wasmJsTest by getting {
dependsOn(nonJsTest)
dependsOn(wasmTest)
}
val wasmWasiMain by getting {
dependsOn(nonJsMain)
dependsOn(wasmMain)
}
val wasmWasiTest by getting {
dependsOn(nonJsTest)
dependsOn(wasmTest)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,38 +25,36 @@ internal fun calcHuForRegular(regularPattern: RegularHoraHandPattern, hasRenpuuJ
var ans = 20

// 单骑、边张、坎张听牌
if (agariTatsu == null || agariTatsu is Penchan || agariTatsu is Kanchan) {
if (agariTatsu == null || agariTatsu.type == TatsuType.Penchan || agariTatsu.type == TatsuType.Kanchan) {
ans += 2
}

// 明刻、杠
furo.forEach { fr ->
if (fr is Pon) {
if (fr.type == FuroType.Pon) {
if (fr.tile.isYaochu) {
ans += 4
} else {
ans += 2
}
} else if (fr is Kan) {
if (!fr.ankan) {
if (fr.tile.isYaochu) {
ans += 16
} else {
ans += 8
}
} else if (fr.type == FuroType.Ankan) {
if (fr.tile.isYaochu) {
ans += 32
} else {
if (fr.tile.isYaochu) {
ans += 32
} else {
ans += 16
}
ans += 16
}
} else if (fr.type == FuroType.Kan) {
if (fr.tile.isYaochu) {
ans += 16
} else {
ans += 8
}
}
}

// 暗刻(不含暗杠)
menzenMentsu.forEach { mt ->
if (mt is Kotsu) {
if (mt.type == MentsuType.Kotsu) {
if (mt.tile.isYaochu) {
ans += 8
} else {
Expand All @@ -66,7 +64,7 @@ internal fun calcHuForRegular(regularPattern: RegularHoraHandPattern, hasRenpuuJ
}

// 对碰荣和时该刻子计为明刻
if (agariTatsu is Toitsu && !tsumo) {
if (agariTatsu?.type == TatsuType.Toitsu && !tsumo) {
ans -= 2
}

Expand Down
127 changes: 57 additions & 70 deletions mahjong-utils/src/commonMain/kotlin/mahjongutils/models/Furo.kt
Original file line number Diff line number Diff line change
@@ -1,23 +1,53 @@
@file:OptIn(ExperimentalSerializationApi::class)

package mahjongutils.models

import kotlinx.serialization.EncodeDefault
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlin.jvm.JvmInline

enum class FuroType {
Chi, Pon, Kan, Ankan
}

@JvmInline
@Serializable(FuroSerializer::class)
value class Furo private constructor(private val value: Int) {
constructor(type: FuroType, tile: Tile) : this(type.ordinal * 100 + tile.code)

val type: FuroType
get() = FuroType.entries[value / 100]

val tile: Tile
get() = Tile[value % 100]

/**
* 副露
*/
@Serializable
sealed interface Furo {
/**
* 获取副露的面子
*/
fun asMentsu(): Mentsu
fun asMentsu(): Mentsu {
return when (type) {
FuroType.Chi -> Shuntsu(tile)
FuroType.Pon, FuroType.Kan, FuroType.Ankan -> Kotsu(tile)
}
}

val tiles: List<Tile>
get() = when (type) {
FuroType.Chi -> listOf(tile, tile.advance(1), tile.advance(2))
FuroType.Pon -> listOf(tile, tile, tile)
FuroType.Kan, FuroType.Ankan -> listOf(tile, tile, tile, tile)
}

override fun toString(): String {
return when (type) {
FuroType.Chi -> "${tile.num}${tile.realNum + 1}${tile.realNum + 2}${tile.type.name.lowercase()}"
FuroType.Pon -> "${tile.num}${tile.num}${tile.num}${tile.type.name.lowercase()}"
FuroType.Kan -> "${tile.num}${tile.num}${tile.num}${tile.num}${tile.type.name.lowercase()}"
FuroType.Ankan -> "0${tile.num}${tile.num}0${tile.type.name.lowercase()}"
}
}

companion object {
/**
Expand All @@ -44,7 +74,11 @@ sealed interface Furo {
}
} else if (tiles.size == 4) {
if (tiles[0] == tiles[1] && tiles[1] == tiles[2] && tiles[2] == tiles[3]) {
return Kan(tiles[0], ankan)
if (!ankan) {
return Kan(tiles[0])
} else {
return Ankan(tiles[0])
}
}
}

Expand Down Expand Up @@ -72,10 +106,6 @@ sealed interface Furo {
}
}

fun Furo(vararg tiles: Tile, ankan: Boolean = false): Furo {
return Furo.parse(tiles.toList(), ankan)
}

fun Furo(tiles: List<Tile>, ankan: Boolean = false): Furo {
return Furo.parse(tiles, ankan)
}
Expand All @@ -84,63 +114,20 @@ fun Furo(text: String, ankan: Boolean = false): Furo {
return Furo.parse(text, ankan)
}

/**
* 吃
*/
@Serializable
@SerialName("Chi")
data class Chi(
/**
* 吃成的顺子的第一张牌(如789m,tile应为7m)
*/
val tile: Tile
) : Furo {
override fun asMentsu(): Shuntsu {
return Shuntsu(tile)
}
fun Chi(tile: Tile) = Furo(FuroType.Chi, tile)
fun Pon(tile: Tile) = Furo(FuroType.Pon, tile)
fun Kan(tile: Tile) = Furo(FuroType.Kan, tile)
fun Ankan(tile: Tile) = Furo(FuroType.Ankan, tile)

override val tiles: List<Tile>
get() = listOf(tile, tile.advance(1), tile.advance(2))
}
object FuroSerializer : KSerializer<Furo> {
override val descriptor = PrimitiveSerialDescriptor("Furo", PrimitiveKind.STRING)

/**
* 碰
*/
@Serializable
@SerialName("Pon")
data class Pon(
/**
* 碰成的刻子的牌(如777s,tile应为7s)
*/
val tile: Tile
) : Furo {
override fun asMentsu(): Kotsu {
return Kotsu(tile)
override fun serialize(encoder: Encoder, value: Furo) {
encoder.encodeString(value.toString())
}

override val tiles: List<Tile>
get() = listOf(tile, tile, tile)
}

/**
* 杠
*/
@Serializable
@SerialName("Kan")
data class Kan(
/**
* 杠成的刻子的牌(如7777s,tile应为7s)
*/
val tile: Tile,
/**
* 是否为暗杠
*/
@EncodeDefault val ankan: Boolean = false
) : Furo {
override fun asMentsu(): Kotsu {
return Kotsu(tile)
override fun deserialize(decoder: Decoder): Furo {
val text = decoder.decodeString()
return Furo(text)
}

override val tiles: List<Tile>
get() = listOf(tile, tile, tile, tile)
}
Loading

0 comments on commit d1c29b3

Please sign in to comment.