26 Commits
Author SHA1 Message Date
me c82fdd28cf Merge pull request '1.1.2' (#3) from dev into main
Reviewed-on: #3
2026-11-01 10:34:50 -07:00
me 169d30f81f changelog, add historic data from Releases page. 2026-11-01 10:33:58 -07:00
me 7799ce100c changelog, add file. 2026-11-01 10:31:41 -07:00
me 0935d7da52 main, fix app sometimes being underneath home row buttons (home, back, recent). 2026-11-01 10:27:35 -07:00
me b7a7be8a60 build, update version. 2026-11-01 10:27:08 -07:00
me c63416489c icon, fix Android Studio's screw up of the background color, color picker is bugged and fixing it in the XML afterwards did not do any sort of reapply. 2026-11-01 10:11:20 -07:00
me 4a237c8268 Merge pull request '1.1.1' (#2) from dev into main
Reviewed-on: #2
2026-11-01 09:58:58 -07:00
me bb8cc12fb7 icon, import via Android Studio so that it works on all versions of Android. 2026-11-01 09:55:54 -07:00
me b6d95f9268 Update versions and migrate to Kotlin Compose so that app compiles successfully, otherwise was in a stuck failed state due to deprecations. 2026-11-01 09:55:32 -07:00
me cbfa94131b Update Gradle. 2026-10-22 17:31:52 -07:00
me ab8959c3f4 fdroid, add specifier to email and put the field in the app-specific section. 2026-09-29 07:16:39 -07:00
me a1b7f180a2 Add more fdroid details while refactoring the file. 2026-07-04 15:00:56 -07:00
me c984624895 Update issue tracker to be proper HTTP link, use contact page. Change website page to go directly to the app. 2026-07-04 10:45:40 -07:00
me 6f68bc1b04 Add manifest file for fdroid server. 2026-07-03 17:34:51 -07:00
me e7b377bdb9 Merge pull request 'v1.1.0 - Update Android Target; Release Old Commits' (#1) from dev into main
Reviewed-on: #1
2025-08-17 09:35:20 -07:00
me 54dadb1f25 Run AGP Upgrade Assistant. 2025-08-17 09:18:07 -07:00
me f2ede2767d Remove extra whitespace. 2025-07-23 07:47:29 -07:00
me 59af3a2485 Fix location of app and its downloads. 2025-07-23 05:26:05 -07:00
me 5f40507a7d Upgrade gradle version. 2025-07-23 05:25:54 -07:00
me 920ee0d54c Upgrade minor versions since this release will include unreleased game changes. 2025-07-23 05:25:46 -07:00
me f992d25d29 AGP Upgrade Assistant. 2025-01-02 15:34:05 -07:00
me 6eb2811814 Update the GitHub button due to my migration off of there. ;) 2025-01-02 15:21:17 -07:00
me f552cc77a8 Increment the version before making any changes. 2025-01-02 15:20:27 -07:00
me 07cefd2776 Studio upgraded the gradle version. 2024-07-01 15:03:14 -07:00
me 59082be0cf Make the AI a little more consistent by using += instead of =. 2024-04-04 12:13:39 -07:00
me 31703cffb9 Fix UI being too tall for some devices. 2024-04-04 12:06:00 -07:00
42 changed files with 246 additions and 136 deletions

No files matched your search

+2 -2
View File
@@ -8,9 +8,9 @@ and maybe even make the game mad. 🐇🥚
## Download
App is hosted at [Hyperling.com](https://hyperling.com/home/#tictactoe) where
App is hosted at [git.hyperling.com](https://git.hyperling.com/me/android-tictactoe) where
it is also available for
[Direct Download](https://hyperling.com/files/apks/TicTacToe.apk).
[Direct Download](https://git.hyperling.com/me/android-tictactoe/releases).
## TODO
+28
View File
@@ -0,0 +1,28 @@
# Changelog
Update history of this app.
## 1.1.2
**More Fixes**
- Correctly apply background color 333333 to icons.
- Ensure activity sits above the navigation buttons on newer version of Android (if they exist).
## 1.1.0
**Fix App Icon**
- Fix app icon for some versions of Android.
- Update to the latest versions of internal plugins so that app can be compiled successfully.
- Now targets Android SDK 37.
## 1.1.0
**Update Android Target; Release Old Commits**
- Update to SDK 36.
- AI fixes and UI improvements.
- Correct download URL.
Note that this release uses a new key due to the old one not existing in the keystore.
+21 -14
View File
@@ -1,18 +1,19 @@
plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.jetbrainsKotlinAndroid)
//alias(libs.plugins.jetbrainsKotlinAndroid)
alias(libs.plugins.kotlinCompose)
}
android {
namespace = "com.hyperling.tictactoe"
compileSdk = 34
compileSdk = 37
defaultConfig {
applicationId = "com.hyperling.tictactoe"
minSdk = 21
targetSdk = 34
versionCode = 1
versionName = "1.0"
minSdk = 23
targetSdk = 37
versionCode = 6
versionName = "1.1.2"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
@@ -22,16 +23,17 @@ android {
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
buildFeatures {
compose = true
@@ -47,7 +49,6 @@ android {
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
@@ -63,4 +64,10 @@ dependencies {
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
// 2026-11-01 - Fix for "unresolved reference" on these in MainActivity:
//import androidx.compose.material.icons.Icons
//import androidx.compose.material.icons.rounded.Close
implementation("androidx.compose.material:material-icons-core")
implementation("androidx.compose.material:material-icons-extended")
}
+1 -2
View File
@@ -10,8 +10,7 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_icon_ttt"
android:supportsRtl="true"
android:theme="@style/Theme.TicTacToe"
tools:targetApi="31">
android:theme="@style/Theme.TicTacToe">
<activity
android:name=".MainActivity"
android:exported="true"
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

@@ -7,6 +7,7 @@ import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons
@@ -28,12 +29,17 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
TicTacToeTheme {
Box(Modifier.fillMaxSize().systemBarsPadding()) {
Surface {
Game()
}
@@ -41,6 +47,7 @@ class MainActivity : ComponentActivity() {
}
}
}
}
@Composable
fun Game() {
@@ -194,8 +201,8 @@ fun Game() {
Column(
horizontalAlignment = Alignment.CenterHorizontally
, verticalArrangement = Arrangement.Center
, modifier = Modifier
.fillMaxSize()
//, modifier = Modifier
// .fillMaxSize()
) {
Spacer(modifier = Modifier.weight(0.1f))
@@ -346,6 +353,15 @@ fun Game() {
fontSize = 16.sp
)
Spacer(modifier = Modifier.size(5.dp))
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly
) {
Column (
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.Top
) {
Row (
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.clickable {
@@ -361,21 +377,6 @@ fun Game() {
fontSize = 16.sp
)
}
Row (
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.clickable {
opponentRandom = setRadiosFalse()
}
){
RadioButton(
selected = opponentRandom,
onClick = { opponentRandom = setRadiosFalse() },
)
Text(
text = stringResource(id = R.string.opponent_random),
fontSize = 16.sp
)
}
Row (
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.clickable {
@@ -391,21 +392,6 @@ fun Game() {
fontSize = 16.sp
)
}
Row (
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.clickable {
opponentEasy = setRadiosFalse()
}
){
RadioButton(
selected = opponentEasy,
onClick = { opponentEasy = setRadiosFalse() },
)
Text(
text = stringResource(id = R.string.opponent_easy),
fontSize = 16.sp
)
}
Row (
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.clickable {
@@ -421,6 +407,42 @@ fun Game() {
fontSize = 16.sp
)
}
}
Column (
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.Bottom
) {
Row (
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.clickable {
opponentRandom = setRadiosFalse()
}
){
RadioButton(
selected = opponentRandom,
onClick = { opponentRandom = setRadiosFalse() },
)
Text(
text = stringResource(id = R.string.opponent_random),
fontSize = 16.sp
)
}
Row (
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.clickable {
opponentEasy = setRadiosFalse()
}
){
RadioButton(
selected = opponentEasy,
onClick = { opponentEasy = setRadiosFalse() },
)
Text(
text = stringResource(id = R.string.opponent_easy),
fontSize = 16.sp
)
}
Row (
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.clickable {
@@ -437,6 +459,8 @@ fun Game() {
)
}
}
}
}
Spacer(modifier = Modifier.weight(.05f))
// */
@@ -632,10 +656,10 @@ fun playWeightedMove(grid: MutableList<String>, behavior: Int, piece: String) :
// Easy, does not prevent human from winning and may try to win.
0 -> {
causeWin = 100
preventLoss = -1
middle = 1
corner = 1
side = 1
preventLoss = -25
middle = 0
corner = 0
side = 0
}
// Hard, will try to win for itself and prevent the human from winning.
1 -> {
@@ -647,7 +671,7 @@ fun playWeightedMove(grid: MutableList<String>, behavior: Int, piece: String) :
}
// Annoying / stubborn, will not let you win but also will not try to win.
2 -> {
causeWin = 99
causeWin = -25
preventLoss = 100
middle = 4
corner = 3
@@ -655,11 +679,11 @@ fun playWeightedMove(grid: MutableList<String>, behavior: Int, piece: String) :
}
// Shy, refuses to complete the game unless it's the only move left.
3 -> {
causeWin = -1
preventLoss = -1
middle = 1
corner = 1
side = 1
causeWin = -25
preventLoss = -25
middle = 4
corner = 3
side = 2
}
// Random! No need for the other function anymore. ;)
else -> {
@@ -680,132 +704,131 @@ fun playWeightedMove(grid: MutableList<String>, behavior: Int, piece: String) :
// Top Row, Win Conditions
if (grid[0] == piece && grid[1] == piece && grid[2].isBlank())
weights[2] = causeWin
weights[2] += causeWin
if (grid[0] == piece && grid[1].isBlank() && grid[2] == piece)
weights[1] = causeWin
weights[1] += causeWin
if (grid[0].isBlank() && grid[1] == piece && grid[2] == piece)
weights[0] = causeWin
weights[0] += causeWin
// Top Row, Lose Conditions
if (grid[0] == human && grid[1] == human && grid[2].isBlank())
weights[2] = preventLoss
weights[2] += preventLoss
if (grid[0] == human && grid[1].isBlank() && grid[2] == human)
weights[1] = preventLoss
weights[1] += preventLoss
if (grid[0].isBlank() && grid[1] == human && grid[2] == human)
weights[0] = preventLoss
weights[0] += preventLoss
// Middle Row, Win Conditions
if (grid[3] == piece && grid[4] == piece && grid[5].isBlank())
weights[5] = causeWin
weights[5] += causeWin
if (grid[3] == piece && grid[4].isBlank() && grid[5] == piece)
weights[4] = causeWin
weights[4] += causeWin
if (grid[3].isBlank() && grid[4] == piece && grid[5] == piece)
weights[3] = causeWin
weights[3] += causeWin
// Middle Row, Lose Conditions
if (grid[3] == human && grid[4] == human && grid[5].isBlank())
weights[5] = preventLoss
weights[5] += preventLoss
if (grid[3] == human && grid[4].isBlank() && grid[5] == human)
weights[4] = preventLoss
weights[4] += preventLoss
if (grid[3].isBlank() && grid[4] == human && grid[5] == human)
weights[3] = preventLoss
weights[3] += preventLoss
// Bottom Row, Win Conditions
if (grid[6] == piece && grid[7] == piece && grid[8].isBlank())
weights[8] = causeWin
weights[8] += causeWin
if (grid[6] == piece && grid[7].isBlank() && grid[8] == piece)
weights[7] = causeWin
weights[7] += causeWin
if (grid[6].isBlank() && grid[7] == piece && grid[8] == piece)
weights[6] = causeWin
weights[6] += causeWin
// Bottom Row, Lose Conditions
if (grid[6] == human && grid[7] == human && grid[8].isBlank())
weights[8] = preventLoss
weights[8] += preventLoss
if (grid[6] == human && grid[7].isBlank() && grid[8] == human)
weights[7] = preventLoss
weights[7] += preventLoss
if (grid[6].isBlank() && grid[7] == human && grid[8] == human)
weights[6] = preventLoss
weights[6] += preventLoss
// Left Column, Win Conditions
if (grid[0] == piece && grid[3] == piece && grid[6].isBlank())
weights[6] = causeWin
weights[6] += causeWin
if (grid[0] == piece && grid[3].isBlank() && grid[6] == piece)
weights[3] = causeWin
weights[3] += causeWin
if (grid[0].isBlank() && grid[3] == piece && grid[6] == piece)
weights[0] = causeWin
weights[0] += causeWin
// Left Column, Lose Conditions
if (grid[0] == human && grid[3] == human && grid[6].isBlank())
weights[6] = preventLoss
weights[6] += preventLoss
if (grid[0] == human && grid[3].isBlank() && grid[6] == human)
weights[3] = preventLoss
weights[3] += preventLoss
if (grid[0].isBlank() && grid[3] == human && grid[6] == human)
weights[0] = preventLoss
weights[0] += preventLoss
// Middle Column, Win Conditions
if (grid[1] == piece && grid[4] == piece && grid[7].isBlank())
weights[7] = causeWin
weights[7] += causeWin
if (grid[1] == piece && grid[4].isBlank() && grid[7] == piece)
weights[4] = causeWin
weights[4] += causeWin
if (grid[1].isBlank() && grid[4] == piece && grid[7] == piece)
weights[1] = causeWin
weights[1] += causeWin
// Middle Column, Lose Conditions
if (grid[1] == human && grid[4] == human && grid[7].isBlank())
weights[7] = preventLoss
weights[7] += preventLoss
if (grid[1] == human && grid[4].isBlank() && grid[7] == human)
weights[4] = preventLoss
weights[4] += preventLoss
if (grid[1].isBlank() && grid[4] == human && grid[7] == human)
weights[1] = preventLoss
weights[1] += preventLoss
// Right Column, Win Conditions
if (grid[2] == piece && grid[5] == piece && grid[8].isBlank())
weights[8] = causeWin
weights[8] += causeWin
if (grid[2] == piece && grid[5].isBlank() && grid[8] == piece)
weights[5] = causeWin
weights[5] += causeWin
if (grid[2].isBlank() && grid[5] == piece && grid[8] == piece)
weights[2] = causeWin
weights[2] += causeWin
// Right Column, Lose Conditions
if (grid[2] == human && grid[5] == human && grid[8].isBlank())
weights[8] = preventLoss
weights[8] += preventLoss
if (grid[2] == human && grid[5].isBlank() && grid[8] == human)
weights[5] = preventLoss
weights[5] += preventLoss
if (grid[2].isBlank() && grid[5] == human && grid[8] == human)
weights[2] = preventLoss
weights[2] += preventLoss
// Top Left Diagonal, Win Conditions
if (grid[0] == piece && grid[4] == piece && grid[8].isBlank())
weights[8] = causeWin
weights[8] += causeWin
if (grid[0] == piece && grid[4].isBlank() && grid[8] == piece)
weights[4] = causeWin
weights[4] += causeWin
if (grid[0].isBlank() && grid[4] == piece && grid[8] == piece)
weights[0] = causeWin
weights[0] += causeWin
// Top Left Diagonal, Lose Conditions
if (grid[0] == human && grid[4] == human && grid[8].isBlank())
weights[8] = preventLoss
weights[8] += preventLoss
if (grid[0] == human && grid[4].isBlank() && grid[8] == human)
weights[4] = preventLoss
weights[4] += preventLoss
if (grid[0].isBlank() && grid[4] == human && grid[8] == human)
weights[0] = preventLoss
weights[0] += preventLoss
// Top Right Diagonal, Win Conditions
if (grid[2] == piece && grid[4] == piece && grid[6].isBlank())
weights[6] = causeWin
weights[6] += causeWin
if (grid[2] == piece && grid[4].isBlank() && grid[6] == piece)
weights[4] = causeWin
weights[4] += causeWin
if (grid[2].isBlank() && grid[4] == piece && grid[6] == piece)
weights[2] = causeWin
weights[2] += causeWin
// Top Right Diagonal, Lose Conditions
if (grid[2] == human && grid[4] == human && grid[6].isBlank())
weights[6] = preventLoss
weights[6] += preventLoss
if (grid[2] == human && grid[4].isBlank() && grid[6] == human)
weights[4] = preventLoss
weights[4] += preventLoss
if (grid[2].isBlank() && grid[4] == human && grid[6] == human)
weights[2] = preventLoss
weights[2] += preventLoss
// */
// Set all the played pieces to a very low number.
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="273"
android:viewportHeight="168.75">
<group android:scaleX="0.46"
android:scaleY="0.28434065"
android:translateX="73.71"
android:translateY="60.38376">
<group android:translateY="133.59375">
<path android:pathData="M57.375,-102.375L57.375,-0L32.703125,-0L32.703125,-102.375L57.375,-102.375ZM88.171875,-102.375L88.171875,-83.328125L2.609375,-83.328125L2.609375,-102.375L88.171875,-102.375Z"
android:fillColor="#333333"/>
<path android:pathData="M148.375,-102.375L148.375,0L123.703125,0L123.703125,-102.375L148.375,-102.375ZM179.17188,-102.375L179.17188,-83.328125L93.609375,-83.328125L93.609375,-102.375L179.17188,-102.375Z"
android:fillColor="#333333"/>
<path android:pathData="M239.375,-102.375L239.375,0L214.70312,0L214.70312,-102.375L239.375,-102.375ZM270.17188,-102.375L270.17188,-83.328125L184.60938,-83.328125L184.60938,-102.375L270.17188,-102.375Z"
android:fillColor="#333333"/>
</group>
</group>
</vector>
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_monochrome"/>
</adaptive-icon>
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_monochrome"/>
</adaptive-icon>
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 872 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#333333</color>
</resources>
+8 -8
View File
@@ -2,15 +2,15 @@
<string name="app_name">Tic-Tac-Toe</string>
<string name="opponent_header">Choose your opponent:</string>
<string name="opponent_human">Human - Someone next to you.</string>
<string name="opponent_random">AI : Random - Fills any open spot.</string>
<string name="opponent_hard">AI : Hard - Your typical try-hard.</string>
<string name="opponent_easy">AI : Easy - Opportunist, may try to win.</string>
<string name="opponent_annoying">AI : Stubborn - Won\'t let you win.</string>
<string name="opponent_shy">AI : Shy - Too scared to win.</string>
<string name="opponent_human">Human</string>
<string name="opponent_random">AI : Random</string>
<string name="opponent_hard">AI : Hard</string>
<string name="opponent_easy">AI : Easy</string>
<string name="opponent_annoying">AI : Stubborn</string>
<string name="opponent_shy">AI : Shy</string>
<string name="link1_text">Website</string>
<string name="link1_uri">https://hyperling.com</string>
<string name="link2_text">GitHub</string>
<string name="link2_uri">https://github.com/Hyperling/TicTacToeAndroid</string>
<string name="link2_text">Source Code</string>
<string name="link2_uri">https://git.hyperling.com/me/android-tictactoe</string>
</resources>
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

+2 -1
View File
@@ -1,5 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
alias(libs.plugins.androidApplication) apply false
alias(libs.plugins.jetbrainsKotlinAndroid) apply false
//alias(libs.plugins.jetbrainsKotlinAndroid) apply false
alias(libs.plugins.kotlinCompose) apply false
}
+16
View File
@@ -0,0 +1,16 @@
AuthorName: 'Chad Michael "Hyperling" Greenwood'
AuthorWebSite: 'https://hyperling.com/about/'
Donate: 'https://hyperling.com/donate/'
Liberapay: 'HyperVegan'
Bitcoin: 'bc1qsfe8dkvry3d34kztz449gkq67wq8fu2nkgfkh0'
Litecoin: 'ltc1qavmpu5d6ljntxsd6jj548m4yys83zwscl0dzkx'
IssueTracker: 'https://hyperling.com/contact/'
Categories:
- fdroid
- hyperling
- games
Name: Tic-Tac-Toe
AuthorEmail: 'me+tictactoe@hyperling.com'
Summary: 'Play against a friend or a range of AIs. Written to practice Kotlin/Compose.'
SourceCode: 'https://git.hyperling.com/me/android-tictactoe/'
WebSite: 'https://hyperling.com/apps/#tictactoe'
+12
View File
@@ -0,0 +1,12 @@
#This file is generated by updateDaemonJvm
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/cf726b4a1c84b50457225f9bba6d7650/redirect
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/fa1e318c287360478e3c83a9a3ef1007/redirect
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/cf726b4a1c84b50457225f9bba6d7650/redirect
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/fa1e318c287360478e3c83a9a3ef1007/redirect
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/c2dd35c9d0aaf0ba6ad0791320f99dfc/redirect
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/e5810bd7fd1f8a586644409d395a7e55/redirect
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/cf726b4a1c84b50457225f9bba6d7650/redirect
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/fa1e318c287360478e3c83a9a3ef1007/redirect
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/7b3c4877c0749019e6805bb61e421497/redirect
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/d76df094a9cbbabd3b08251f9e61444a/redirect
toolchainVersion=25
+10 -10
View File
@@ -1,13 +1,13 @@
[versions]
agp = "8.3.1"
kotlin = "1.9.0"
coreKtx = "1.10.1"
agp = "9.5.0"
kotlin = "2.4.21"
coreKtx = "1.19.1"
junit = "4.13.2"
junitVersion = "1.1.5"
espressoCore = "3.5.1"
lifecycleRuntimeKtx = "2.6.1"
activityCompose = "1.7.0"
composeBom = "2023.08.00"
junitVersion = "1.3.0"
espressoCore = "3.7.0"
lifecycleRuntimeKtx = "2.11.0"
activityCompose = "1.13.0"
composeBom = "2026.09.00"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -27,5 +27,5 @@ androidx-material3 = { group = "androidx.compose.material3", name = "material3"
[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
jetbrainsKotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
#jetbrainsKotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlinCompose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
+2 -2
View File
@@ -1,6 +1,6 @@
#Sat Mar 30 12:28:25 MST 2024
#Sun Nov 01 08:44:00 MST 2026
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists