From 2d1911ff3d6015bfd9c633400e98d8454a998f34 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Sat, 29 Oct 2022 01:27:47 +1100 Subject: [PATCH 1/9] Added explicit request for a gradle build submodule --- .gitmodules | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..da9078ed --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "basic-computer-games-gradle"] + path = basic-computer-games-gradle + url = https://github.com/pcholt/basic-computer-games-gradle.git From 986c8732711a3bb62d0a461faf33e251ec4049ca Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Fri, 4 Nov 2022 23:45:15 +1100 Subject: [PATCH 2/9] bullfight added --- 17_Bullfight/bullfight.bas | 140 ++++++++++++--------- 17_Bullfight/kotlin/src/bullfight/Main.kt | 144 ++++++++++++++++++++++ 2 files changed, 229 insertions(+), 55 deletions(-) create mode 100644 17_Bullfight/kotlin/src/bullfight/Main.kt diff --git a/17_Bullfight/bullfight.bas b/17_Bullfight/bullfight.bas index 32b04b89..a2aa45b7 100644 --- a/17_Bullfight/bullfight.bas +++ b/17_Bullfight/bullfight.bas @@ -6,25 +6,25 @@ 205 PRINT "DO YOU WANT INSTRUCTIONS"; 206 INPUT Z$ 207 IF Z$="NO" THEN 400 -210 PRINT "HELLO, ALL YOU BLOODLOVERS AND AFICIONADOS." -220 PRINT "HERE IS YOUR BIG CHANCE TO KILL A BULL." -230 PRINT -240 PRINT "ON EACH PASS OF THE BULL, YOU MAY TRY" -250 PRINT "0 - VERONICA (DANGEROUS INSIDE MOVE OF THE CAPE)" -260 PRINT "1 - LESS DANGEROUS OUTSIDE MOVE OF THE CAPE" -270 PRINT "2 - ORDINARY SWIRL OF THE CAPE." -280 PRINT -290 PRINT "INSTEAD OF THE ABOVE, YOU MAY TRY TO KILL THE BULL" -300 PRINT "ON ANY TURN: 4 (OVER THE HORNS), 5 (IN THE CHEST)." -310 PRINT "BUT IF I WERE YOU," -320 PRINT "I WOULDN'T TRY IT BEFORE THE SEVENTH PASS." -330 PRINT -340 PRINT "THE CROWD WILL DETERMINE WHAT AWARD YOU DESERVE" -350 PRINT "(POSTHUMOUSLY IF NECESSARY)." -360 PRINT "THE BRAVER YOU ARE, THE BETTER THE AWARD YOU RECEIVE." -370 PRINT -380 PRINT "THE BETTER THE JOB THE PICADORES AND TOREADORES DO," -390 PRINT "THE BETTER YOUR CHANCES ARE." + println("HELLO, ALL YOU BLOODLOVERS AND AFICIONADOS.") + println("HERE IS YOUR BIG CHANCE TO KILL A BULL.") + println() + println("ON EACH PASS OF THE BULL, YOU MAY TRY") + println("0 - VERONICA (DANGEROUS INSIDE MOVE OF THE CAPE)") + println("1 - LESS DANGEROUS OUTSIDE MOVE OF THE CAPE") + println("2 - ORDINARY SWIRL OF THE CAPE.") + println() + println("INSTEAD OF THE ABOVE, YOU MAY TRY TO KILL THE BULL") + println("ON ANY TURN: 4 (OVER THE HORNS), 5 (IN THE CHEST).") + println("BUT IF I WERE YOU,") + println("I WOULDN'T TRY IT BEFORE THE SEVENTH PASS.") + println() + println("THE CROWD WILL DETERMINE WHAT AWARD YOU DESERVE") + println("(POSTHUMOUSLY IF NECESSARY).") + println("THE BRAVER YOU ARE, THE BETTER THE AWARD YOU RECEIVE.") + println() + println("THE BETTER THE JOB THE PICADORES AND TOREADORES DO,") + println("THE BETTER YOUR CHANCES ARE.") 400 PRINT 410 PRINT 420 D(5)=1 @@ -32,55 +32,70 @@ 450 DIM L$(5) 455 A=INT(RND(1)*5+1) 460 FOR I=1 TO 5 -463 READ L$(I) + 463 READ L$(I) 467 NEXT I 470 DATA "SUPERB","GOOD","FAIR","POOR","AWFUL" 490 PRINT "YOU HAVE DRAWN A ";L$(A);" BULL." 500 IF A>4 THEN 530 -510 IF A<2 THEN 550 -520 GOTO 570 -530 PRINT "YOU'RE LUCKY." -540 GOTO 570 -550 PRINT "GOOD LUCK. YOU'LL NEED IT." -560 PRINT + + 510 IF A<2 THEN 550 + 520 GOTO 570 + + 530 PRINT "YOU'RE LUCKY." + 540 GOTO 570 + + 550 PRINT "GOOD LUCK. YOU'LL NEED IT." + 560 PRINT + 570 PRINT + 590 A$="PICADO" 595 B$="RES" 600 GOSUB 1610 + 610 D(1)=C + 630 A$="TOREAD" 635 B$="ORES" 640 GOSUB 1610 + 650 D(2)=C 660 PRINT 670 PRINT 680 IF Z=1 THEN 1310 + 690 D(3)=D(3)+1 700 PRINT "PASS NUMBER";D(3) 710 IF D(3)<3 THEN 760 -720 PRINT "HERE COMES THE BULL. TRY FOR A KILL"; -730 GOSUB 1930 -735 IF Z1=1 THEN 1130 -740 PRINT "CAPE MOVE"; -750 GOTO 800 -760 PRINT "THE BULL IS CHARGING AT YOU! YOU ARE THE MATADOR--" -770 PRINT "DO YOU WANT TO KILL THE BULL"; -780 GOSUB 1930 -785 IF Z1=1 THEN 1130 -790 PRINT "WHAT MOVE DO YOU MAKE WITH THE CAPE"; + + 720 PRINT "HERE COMES THE BULL. TRY FOR A KILL"; + 730 GOSUB 1930 + 735 IF Z1=1 THEN 1130 + 740 PRINT "CAPE MOVE"; + 750 GOTO 800 +#else + 760 PRINT "THE BULL IS CHARGING AT YOU! YOU ARE THE MATADOR--" + 770 PRINT "DO YOU WANT TO KILL THE BULL"; + 780 GOSUB 1930 + 785 IF Z1=1 THEN 1130 + 790 PRINT "WHAT MOVE DO YOU MAKE WITH THE CAPE"; + 800 INPUT E 810 IF E<>INT(ABS(E)) THEN 830 -820 IF E<3 THEN 850 -830 PRINT "DON'T PANIC, YOU IDIOT! PUT DOWN A CORRECT NUMBER" -840 GOTO 800 -850 REM + 820 IF E<3 THEN 850 + 830 PRINT "DON'T PANIC, YOU IDIOT! PUT DOWN A CORRECT NUMBER" + 840 GOTO 800 + 850 REM + 860 IF E=0 THEN 920 -870 IF E=1 THEN 900 -880 M=.5 -890 GOTO 930 -900 M=2 -910 GOTO 930 -920 M=3 + 870 IF E=1 THEN 900 + 880 M=.5 + 890 GOTO 930 + 900 M=2 + 910 GOTO 930 +#else + 920 M=3 + 930 L=L+M 940 F=(6-A+M/10)*RND(1)/((D(1)+D(2)+D(3)/10)*5) 950 IF F<.51 THEN 660 @@ -119,6 +134,7 @@ 1280 GOTO 1320 1290 IF K>.8 THEN 960 1300 GOTO 1260 + 1310 PRINT 1320 PRINT 1330 PRINT @@ -149,37 +165,51 @@ 1580 PRINT 1590 PRINT "ADIOS":PRINT:PRINT:PRINT 1600 GOTO 2030 + 1610 B=3/A*RND(1) 1620 IF B<.37 THEN 1740 1630 IF B<.5 THEN 1720 1640 IF B<.63 THEN 1700 1650 IF B<.87 THEN 1680 + 1660 C=.1 1670 GOTO 1750 + 1680 C=.2 1690 GOTO 1750 + 1700 C=.3 1710 GOTO 1750 + 1720 C=.4 1730 GOTO 1750 + 1740 C=.5 + 1750 T=INT(10*C+.2) 1760 PRINT "THE ";A$;B$;" DID A ";L$(T);" JOB." + 1770 IF 4>T THEN 1900 -1780 IF 5=T THEN 1870 -1790 ON FNA(K) GOTO 1830,1850 + 1780 IF 5=T THEN 1870 + 1790 ON FNA(K) GOTO 1830,1850 + + REM Dead code 1800 IF A$="TOREAD" THEN 1820 1810 PRINT "ONE OF THE HORSES OF THE ";A$;B$;" WAS KILLED." 1820 ON FNA(K) GOTO 1830,1850 -1830 PRINT "ONE OF THE ";A$;B$;" WAS KILLED." -1840 GOTO 1900 -1850 PRINT "NO ";A$;B$;" WERE KILLED." -1860 GOTO 1900 -1870 IF A$="TOREAD" THEN 1890 -1880 PRINT FNA(K);"OF THE HORSES OF THE ";A$;B$;" KILLED." -1890 PRINT FNA(K);"OF THE ";A$;B$;" KILLED." + + 1830 PRINT "ONE OF THE ";A$;B$;" WAS KILLED." + 1840 GOTO 1900 + + 1850 PRINT "NO ";A$;B$;" WERE KILLED." + 1860 GOTO 1900 + + 1870 IF A$="TOREAD" THEN 1890 + 1880 PRINT FNA(K);"OF THE HORSES OF THE ";A$;B$;" KILLED." + 1890 PRINT FNA(K);"OF THE ";A$;B$;" KILLED." 1900 PRINT 1910 RETURN + 1920 REM 1930 INPUT A$ 1940 IF A$="YES" THEN 1990 diff --git a/17_Bullfight/kotlin/src/bullfight/Main.kt b/17_Bullfight/kotlin/src/bullfight/Main.kt new file mode 100644 index 00000000..d885bce4 --- /dev/null +++ b/17_Bullfight/kotlin/src/bullfight/Main.kt @@ -0,0 +1,144 @@ +package bullfight + +import bullfight.Yorn.NO +import kotlin.random.Random + +val fna: Int get() = Random.nextInt(1, 2) + +val l = listOf("SUPERB", "GOOD", "FAIR", "POOR", "AWFUL") +var aInt: Int = 0 + +fun main() { + val d = mutableListOf(0f,0f,0f,0f,0f,0f) + intro() + instructions() + d[5] = 1f + d[4] = 1f + + aInt = Random.nextInt(1, 6) + println("YOU HAVE DRAWN A ${l[aInt - 1]} BULL.") + when { + aInt < 2 -> { + println("GOOD LUCK. YOU'LL NEED IT.") + } + + aInt > 4 -> { + println("YOU'RE LUCKY.") + } + + else -> Unit + } + + d[1] = fight(FirstAct.picadores) + d[2] = fight(FirstAct.toreadores) + repeat(2) { println() } + + d[3]++ + println("PASS NUMBER ${d[3]}") + if (d[3]>=3) { + print("HERE COMES THE BULL. TRY FOR A KILL") + if (Yorn.input() == NO) { + print("CAPE MOVE") + } + } + else { + println("THE BULL IS CHARGING AT YOU! YOU ARE THE MATADOR--") + print("DO YOU WANT TO KILL THE BULL") + if (Yorn.input() == NO) { + print("WHAT MOVE DO YOU MAKE WITH THE CAPE") + } + } + + +} + +enum class Yorn(val s: String) { + YES("YES"),NO("NO"); + override fun toString() = s + + companion object { + fun input() : Yorn { + do { + print("? ") + val z1 = readln() + Yorn.values().firstOrNull { z1 == it.s }?.let { return it } ?: println("YES OR NO") + } while (true) + } + } +} + +enum class FirstAct(val str: String) { + picadores("PICADORES"), toreadores("TOREADORES"); + override fun toString() = str +} + +fun fight(firstAct: FirstAct): Float { + + val b = 3.0 / aInt * Random.nextFloat() + val c = when { + b < .37 -> .5f + b < .5 -> .4f + b < .63 -> .3f + b < .87 -> .2f + else -> .1f + } + val t = (10 * c + .2).toInt() + println("THE $firstAct DID A ${l[t - 1]} JOB.") + + if (t >= 4) { + if (t == 5) { + if (firstAct != FirstAct.toreadores) { + println ("$fna OF THE HORSES OF THE $firstAct KILLED.") + } + println("$fna OF THE $firstAct KILLED.") + } + else { + println( + when (fna) { + 1 -> "ONE OF THE $firstAct WAS KILLED." + 2 -> "NO $firstAct WERE KILLED." + else -> "" + } + ) + } + } + println() + + return c +} + +private fun instructions() { + print("DO YOU WANT INSTRUCTIONS? ") + if (readln().trim() != "NO") { + println("HELLO, ALL YOU BLOODLOVERS AND AFICIONADOS.") + println("HERE IS YOUR BIG CHANCE TO KILL A BULL.") + println() + println("ON EACH PASS OF THE BULL, YOU MAY TRY") + println("0 - VERONICA (DANGEROUS INSIDE MOVE OF THE CAPE)") + println("1 - LESS DANGEROUS OUTSIDE MOVE OF THE CAPE") + println("2 - ORDINARY SWIRL OF THE CAPE.") + println() + println("INSTEAD OF THE ABOVE, YOU MAY TRY TO KILL THE BULL") + println("ON ANY TURN: 4 (OVER THE HORNS), 5 (IN THE CHEST).") + println("BUT IF I WERE YOU,") + println("I WOULDN'T TRY IT BEFORE THE SEVENTH PASS.") + println() + println("THE CROWD WILL DETERMINE WHAT AWARD YOU DESERVE") + println("(POSTHUMOUSLY IF NECESSARY).") + println("THE BRAVER YOU ARE, THE BETTER THE AWARD YOU RECEIVE.") + println() + println("THE BETTER THE JOB THE PICADORES AND TOREADORES DO,") + println("THE BETTER YOUR CHANCES ARE.") + } + repeat(2) { + println() + } +} + +fun intro() { + println(" ".repeat(34) + "BULL") + println(" ".repeat(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") + repeat(3) { + println() + } +} From 3dabd1d68dbde9839711f72d0b2d93630e4ecbe0 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Fri, 4 Nov 2022 23:46:47 +1100 Subject: [PATCH 3/9] bullfight added --- basic-computer-games-gradle | 1 + 1 file changed, 1 insertion(+) create mode 160000 basic-computer-games-gradle diff --git a/basic-computer-games-gradle b/basic-computer-games-gradle new file mode 160000 index 00000000..367112cc --- /dev/null +++ b/basic-computer-games-gradle @@ -0,0 +1 @@ +Subproject commit 367112cc067a3623bcca174e354ed671c73c8acb From b5c4354e3dd317ced23ca0a0627aeffe850a60f5 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Mon, 7 Nov 2022 00:04:32 +1100 Subject: [PATCH 4/9] bullfight wip --- 17_Bullfight/kotlin/src/bullfight/Main.kt | 222 ++++++++++++++++++---- 1 file changed, 187 insertions(+), 35 deletions(-) diff --git a/17_Bullfight/kotlin/src/bullfight/Main.kt b/17_Bullfight/kotlin/src/bullfight/Main.kt index d885bce4..c3f6b50e 100644 --- a/17_Bullfight/kotlin/src/bullfight/Main.kt +++ b/17_Bullfight/kotlin/src/bullfight/Main.kt @@ -1,22 +1,25 @@ package bullfight -import bullfight.Yorn.NO +import bullfight.Yorn.* +import kotlin.math.pow import kotlin.random.Random -val fna: Int get() = Random.nextInt(1, 2) +val fna: Boolean get() = Random.nextBoolean() -val l = listOf("SUPERB", "GOOD", "FAIR", "POOR", "AWFUL") +val quality = listOf("SUPERB", "GOOD", "FAIR", "POOR", "AWFUL") var aInt: Int = 0 +var l = 1f +var momentOfTruth = false +val d = mutableListOf(0f, 0f, 0f, 0f, 0f, 0f) fun main() { - val d = mutableListOf(0f,0f,0f,0f,0f,0f) intro() instructions() d[5] = 1f d[4] = 1f aInt = Random.nextInt(1, 6) - println("YOU HAVE DRAWN A ${l[aInt - 1]} BULL.") + println("YOU HAVE DRAWN A ${quality[aInt - 1]} BULL.") when { aInt < 2 -> { println("GOOD LUCK. YOU'LL NEED IT.") @@ -29,46 +32,197 @@ fun main() { else -> Unit } + momentOfTruth() + d[1] = fight(FirstAct.picadores) d[2] = fight(FirstAct.toreadores) repeat(2) { println() } + var gored: Boolean - d[3]++ - println("PASS NUMBER ${d[3]}") - if (d[3]>=3) { - print("HERE COMES THE BULL. TRY FOR A KILL") - if (Yorn.input() == NO) { - print("CAPE MOVE") + gameLoop@ do { + d[3]++ + println("PASS NUMBER ${d[3].toInt()}") + if (d[3] >= 3) { + print("HERE COMES THE BULL. TRY FOR A KILL") + gored = killAttempt("CAPE MOVE") + } else { + println("THE BULL IS CHARGING AT YOU! YOU ARE THE MATADOR--") + print("DO YOU WANT TO KILL THE BULL") + gored = killAttempt("WHAT MOVE DO YOU MAKE WITH THE CAPE") } - } - else { - println("THE BULL IS CHARGING AT YOU! YOU ARE THE MATADOR--") - print("DO YOU WANT TO KILL THE BULL") - if (Yorn.input() == NO) { - print("WHAT MOVE DO YOU MAKE WITH THE CAPE") - } - } + if (!gored) { + val move = restrictedInput( + values = Cape.values(), + errorMessage = "DON'T PANIC, YOU IDIOT! PUT DOWN A CORRECT NUMBER" + ) + val m = when (move) { + Cape.Veronica -> 3f + Cape.Outside -> 2f + Cape.Swirl -> 0.5f + } + + l += m + val f = (6 - aInt + m / 10f) * Random.nextFloat() / ((d[1] + d[2] + d[3] / 10f) * 5f) + if (f < 0.51) + continue + } + + println("THE BULL HAS GORED YOU!") + goreLoop@ do { + when (fna) { + false -> { + println("YOU ARE DEAD.") + d[4] = 1.5f + } + + true -> { + println("YOU ARE STILL ALIVE.") + println() + print("DO YOU RUN FROM THE RING") + when (Yorn.input()) { + + YES -> { + println("COWARD") + d[4] = 0f + } + + NO -> { + println("YOU ARE BRAVE. STUPID, BUT BRAVE.") + when (fna) { + true -> { + d[4] = 2f + continue@gameLoop + } + + false -> { + println("YOU ARE GORED AGAIN!") + continue@goreLoop + } + } + } + } + + } + } + } while (true) + + } while (true) } -enum class Yorn(val s: String) { - YES("YES"),NO("NO"); - override fun toString() = s +fun fnd() = 4.5 + + l / 6 - + (d[1] + d[2]) * 2.5 + + 4 * d[4] + + 2 * d[5] - + d[3].toDouble().pow(2.0) / 120f - + aInt +fun fnc() = fnd() * Random.nextFloat() + +private fun killAttempt(capeMessage: String): Boolean { + when (Yorn.input()) { + YES -> { + when (momentOfTruth()) { + KillResult.Success -> { + println() + println() + if (d[4] == 0f) { + println( + """ + THE CROWD BOOS FOR TEN MINUTES. IF YOU EVER DARE TO SHOW + YOUR FACE IN A RING AGAIN, THEY SWEAR THEY WILL KILL YOU-- + UNLESS THE BULL DOES FIRST. + """.trimIndent() + ) + } + } + + KillResult.Fail -> return true + } + } + + NO -> { + print(capeMessage) + } + } + return false +} + +enum class KillResult { Success, Fail } + +fun momentOfTruth(): KillResult { + momentOfTruth = true + print( + """ + + IT IS THE MOMENT OF TRUTH. + + HOW DO YOU WANT TO KILL THE BULL + """.trimIndent() + ) + + val k = (6 - aInt) * 10 * Random.nextFloat() / ((d[1] + d[2]) * 5 * d[3]) + + val chance = when (stdInput(KillMethod.values())) { + KillMethod.OverHorns -> .8 + KillMethod.Chest -> .2 + null -> { + println("YOU PANICKED. THE BULL GORED YOU.") + return KillResult.Fail + } + } + return if (k <= chance) { + println("YOU KILLED THE BULL!") + d[5] = 2f + KillResult.Success + } else { + println("THE BULL HAS GORED YOU!") + KillResult.Fail + } +} + +interface InputOption { + val input: String +} + +enum class Cape(override val input: String) : InputOption { + Veronica("0"), + Outside("1"), + Swirl("2"), +} + +enum class KillMethod(override val input: String) : InputOption { + OverHorns("4"), + Chest("5"), +} + +private fun stdInput(values: Array): T? { + print("? ") + val z1 = readln() + return values.firstOrNull { z1 == it.input } +} + +private fun restrictedInput(values: Array, errorMessage: String): T { + do { + stdInput(values)?.let { return it } + println(errorMessage) + } while (true) +} + +enum class Yorn(override val input: String) : InputOption { + YES("YES"), NO("NO"); companion object { - fun input() : Yorn { - do { - print("? ") - val z1 = readln() - Yorn.values().firstOrNull { z1 == it.s }?.let { return it } ?: println("YES OR NO") - } while (true) + fun input(): Yorn { + return restrictedInput(values(), "YES OR NO") } } } enum class FirstAct(val str: String) { picadores("PICADORES"), toreadores("TOREADORES"); + override fun toString() = str } @@ -83,21 +237,19 @@ fun fight(firstAct: FirstAct): Float { else -> .1f } val t = (10 * c + .2).toInt() - println("THE $firstAct DID A ${l[t - 1]} JOB.") + println("THE $firstAct DID A ${quality[t - 1]} JOB.") if (t >= 4) { if (t == 5) { if (firstAct != FirstAct.toreadores) { - println ("$fna OF THE HORSES OF THE $firstAct KILLED.") + println("$fna OF THE HORSES OF THE $firstAct KILLED.") } println("$fna OF THE $firstAct KILLED.") - } - else { + } else { println( when (fna) { - 1 -> "ONE OF THE $firstAct WAS KILLED." - 2 -> "NO $firstAct WERE KILLED." - else -> "" + true -> "ONE OF THE $firstAct WAS KILLED." + false -> "NO $firstAct WERE KILLED." } ) } From 486ca64b553f81c131ddd250e462dfc549735fc1 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Sun, 13 Nov 2022 00:51:11 +1100 Subject: [PATCH 5/9] bullfight wip --- 17_Bullfight/kotlin/src/bullfight/Main.kt | 42 ++++++++++++++++++----- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/17_Bullfight/kotlin/src/bullfight/Main.kt b/17_Bullfight/kotlin/src/bullfight/Main.kt index c3f6b50e..582c8ac6 100644 --- a/17_Bullfight/kotlin/src/bullfight/Main.kt +++ b/17_Bullfight/kotlin/src/bullfight/Main.kt @@ -1,9 +1,11 @@ package bullfight import bullfight.Yorn.* -import kotlin.math.pow import kotlin.random.Random +import kotlin.system.exitProcess +private val Float.squared: Float + get() = this * this val fna: Boolean get() = Random.nextBoolean() val quality = listOf("SUPERB", "GOOD", "FAIR", "POOR", "AWFUL") @@ -32,8 +34,6 @@ fun main() { else -> Unit } - momentOfTruth() - d[1] = fight(FirstAct.picadores) d[2] = fight(FirstAct.toreadores) repeat(2) { println() } @@ -116,13 +116,15 @@ fun fnd() = 4.5 + (d[1] + d[2]) * 2.5 + 4 * d[4] + 2 * d[5] - - d[3].toDouble().pow(2.0) / 120f - + d[3].squared / 120f - aInt + fun fnc() = fnd() * Random.nextFloat() private fun killAttempt(capeMessage: String): Boolean { when (Yorn.input()) { - YES -> { + + YES -> when (momentOfTruth()) { KillResult.Success -> { println() @@ -135,16 +137,40 @@ private fun killAttempt(capeMessage: String): Boolean { UNLESS THE BULL DOES FIRST. """.trimIndent() ) + } else { + if (d[4] == 2f) + println("THE CROWD CHEERS WILDLY!") + else + if (d[5] == 2f) { + println("THE CROWD CHEERS!") + println() + } + println("THE CROWD AWARDS YOU") + if (fnc() < 2.4) + println("NOTHING AT ALL.") + else if (fnc() < 4.9) + println("ONE EAR OF THE BULL.") + else + if (fnc() < 7.4) + println("BOTH EARS OF THE BULL!") + else + println("OLE! YOU ARE 'MUY HOMBRE'!! OLE! OLE!") + println() } + println() + println("ADIOS") + println() + println() + println() + exitProcess(0) } KillResult.Fail -> return true } - } - NO -> { + NO -> print(capeMessage) - } + } return false } From b065179603b7599bbac2997d834cd13439f06f55 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Sun, 20 Nov 2022 08:56:55 +1100 Subject: [PATCH 6/9] Add bullfight.bas implementation in kotlin --- 17_Bullfight/kotlin/src/bullfight/Main.kt | 230 +++++++++++++--------- 1 file changed, 132 insertions(+), 98 deletions(-) diff --git a/17_Bullfight/kotlin/src/bullfight/Main.kt b/17_Bullfight/kotlin/src/bullfight/Main.kt index 582c8ac6..7a1a0681 100644 --- a/17_Bullfight/kotlin/src/bullfight/Main.kt +++ b/17_Bullfight/kotlin/src/bullfight/Main.kt @@ -4,51 +4,80 @@ import bullfight.Yorn.* import kotlin.random.Random import kotlin.system.exitProcess +private val Boolean.asInteger get() = if (this) 1 else 2 private val Float.squared: Float get() = this * this -val fna: Boolean get() = Random.nextBoolean() +val fna: Boolean get() = RandomNumbers.nextBoolean() + +enum class Quality(private val typeName: String) { + Superb("SUPERB"), + Good("GOOD"), + Fair("FAIR"), + Poor("POOR"), + Awful("AWFUL"); + override fun toString() = typeName + + val level get() = (ordinal + 1).toFloat() +} + +enum class BullDeath(val factor: Float) { + Alive(1f), Dead(2f); +} -val quality = listOf("SUPERB", "GOOD", "FAIR", "POOR", "AWFUL") -var aInt: Int = 0 var l = 1f +lateinit var bullQuality: Quality var momentOfTruth = false -val d = mutableListOf(0f, 0f, 0f, 0f, 0f, 0f) +var picadoresSuccess = 0f +var toreadoresSuccess = 0f +var passNumber = 0f +var honor = 0f +var bullDeath = BullDeath.Alive + + +interface RandomNumberSource { + fun nextBoolean(): Boolean + fun nextInt(from: Int, until: Int): Int + fun nextFloat(): Float +} + +object RandomNumbers : RandomNumberSource { + override fun nextBoolean() = Random.nextBoolean() + override fun nextInt(from: Int, until: Int) = Random.nextInt(from, until) + override fun nextFloat() = Random.nextFloat() +} + fun main() { intro() instructions() - d[5] = 1f - d[4] = 1f - - aInt = Random.nextInt(1, 6) - println("YOU HAVE DRAWN A ${quality[aInt - 1]} BULL.") - when { - aInt < 2 -> { - println("GOOD LUCK. YOU'LL NEED IT.") - } - - aInt > 4 -> { - println("YOU'RE LUCKY.") - } + bullDeath = BullDeath.Alive + honor = 1f + bullQuality = Quality.values()[RandomNumbers.nextInt(1, 6)] + println("YOU HAVE DRAWN A $bullQuality BULL.") + when (bullQuality) { + Quality.Superb -> println("GOOD LUCK. YOU'LL NEED IT.") + Quality.Awful -> println("YOU'RE LUCKY.") else -> Unit } - d[1] = fight(FirstAct.picadores) - d[2] = fight(FirstAct.toreadores) - repeat(2) { println() } + picadoresSuccess = fight(FirstAct.picadores) + toreadoresSuccess = fight(FirstAct.toreadores) + println() + println() + var gored: Boolean gameLoop@ do { - d[3]++ - println("PASS NUMBER ${d[3].toInt()}") - if (d[3] >= 3) { + passNumber++ + println("PASS NUMBER ${passNumber.toInt()}") + gored = if (passNumber >= 3) { print("HERE COMES THE BULL. TRY FOR A KILL") - gored = killAttempt("CAPE MOVE") + killAttempt("CAPE MOVE") } else { println("THE BULL IS CHARGING AT YOU! YOU ARE THE MATADOR--") print("DO YOU WANT TO KILL THE BULL") - gored = killAttempt("WHAT MOVE DO YOU MAKE WITH THE CAPE") + killAttempt("WHAT MOVE DO YOU MAKE WITH THE CAPE") } if (!gored) { @@ -63,7 +92,8 @@ fun main() { } l += m - val f = (6 - aInt + m / 10f) * Random.nextFloat() / ((d[1] + d[2] + d[3] / 10f) * 5f) + val f = + (6 - bullQuality.level + m / 10f) * RandomNumbers.nextFloat() / ((picadoresSuccess + toreadoresSuccess + passNumber / 10f) * 5f) if (f < 0.51) continue } @@ -73,7 +103,8 @@ fun main() { when (fna) { false -> { println("YOU ARE DEAD.") - d[4] = 1.5f + honor = 1.5f + gameResult() } true -> { @@ -84,14 +115,14 @@ fun main() { YES -> { println("COWARD") - d[4] = 0f + honor = 0f } NO -> { println("YOU ARE BRAVE. STUPID, BUT BRAVE.") when (fna) { true -> { - d[4] = 2f + honor = 2f continue@gameLoop } @@ -113,58 +144,20 @@ fun main() { fun fnd() = 4.5 + l / 6 - - (d[1] + d[2]) * 2.5 + - 4 * d[4] + - 2 * d[5] - - d[3].squared / 120f - - aInt + (picadoresSuccess + toreadoresSuccess) * 2.5 + + 4 * honor + + 2 * bullDeath.factor - + passNumber.squared / 120f - + bullQuality.level -fun fnc() = fnd() * Random.nextFloat() +fun fnc() = fnd() * RandomNumbers.nextFloat() private fun killAttempt(capeMessage: String): Boolean { when (Yorn.input()) { YES -> when (momentOfTruth()) { - KillResult.Success -> { - println() - println() - if (d[4] == 0f) { - println( - """ - THE CROWD BOOS FOR TEN MINUTES. IF YOU EVER DARE TO SHOW - YOUR FACE IN A RING AGAIN, THEY SWEAR THEY WILL KILL YOU-- - UNLESS THE BULL DOES FIRST. - """.trimIndent() - ) - } else { - if (d[4] == 2f) - println("THE CROWD CHEERS WILDLY!") - else - if (d[5] == 2f) { - println("THE CROWD CHEERS!") - println() - } - println("THE CROWD AWARDS YOU") - if (fnc() < 2.4) - println("NOTHING AT ALL.") - else if (fnc() < 4.9) - println("ONE EAR OF THE BULL.") - else - if (fnc() < 7.4) - println("BOTH EARS OF THE BULL!") - else - println("OLE! YOU ARE 'MUY HOMBRE'!! OLE! OLE!") - println() - } - println() - println("ADIOS") - println() - println() - println() - exitProcess(0) - } - + KillResult.Success -> gameResult() KillResult.Fail -> return true } @@ -175,6 +168,45 @@ private fun killAttempt(capeMessage: String): Boolean { return false } +private fun gameResult() { + println() + println() + if (honor == 0f) { + println( + """ + THE CROWD BOOS FOR TEN MINUTES. IF YOU EVER DARE TO SHOW + YOUR FACE IN A RING AGAIN, THEY SWEAR THEY WILL KILL YOU-- + UNLESS THE BULL DOES FIRST. + """.trimIndent() + ) + } else { + if (honor == 2f) + println("THE CROWD CHEERS WILDLY!") + else + if (bullDeath == BullDeath.Dead) { + println("THE CROWD CHEERS!") + println() + } + println("THE CROWD AWARDS YOU") + if (fnc() < 2.4) + println("NOTHING AT ALL.") + else if (fnc() < 4.9) + println("ONE EAR OF THE BULL.") + else + if (fnc() < 7.4) + println("BOTH EARS OF THE BULL!") + else + println("OLE! YOU ARE 'MUY HOMBRE'!! OLE! OLE!") + println() + } + println() + println("ADIOS") + println() + println() + println() + exitProcess(0) +} + enum class KillResult { Success, Fail } fun momentOfTruth(): KillResult { @@ -188,7 +220,8 @@ fun momentOfTruth(): KillResult { """.trimIndent() ) - val k = (6 - aInt) * 10 * Random.nextFloat() / ((d[1] + d[2]) * 5 * d[3]) + val k = + (6 - bullQuality.level) * 10 * RandomNumbers.nextFloat() / ((picadoresSuccess + toreadoresSuccess) * 5 * passNumber) val chance = when (stdInput(KillMethod.values())) { KillMethod.OverHorns -> .8 @@ -200,7 +233,7 @@ fun momentOfTruth(): KillResult { } return if (k <= chance) { println("YOU KILLED THE BULL!") - d[5] = 2f + bullDeath = BullDeath.Dead KillResult.Success } else { println("THE BULL HAS GORED YOU!") @@ -223,12 +256,6 @@ enum class KillMethod(override val input: String) : InputOption { Chest("5"), } -private fun stdInput(values: Array): T? { - print("? ") - val z1 = readln() - return values.firstOrNull { z1 == it.input } -} - private fun restrictedInput(values: Array, errorMessage: String): T { do { stdInput(values)?.let { return it } @@ -236,6 +263,12 @@ private fun restrictedInput(values: Array, errorMessage: St } while (true) } +private fun stdInput(values: Array): T? { + print("? ") + val z1 = readln() + return values.firstOrNull { z1 == it.input } +} + enum class Yorn(override val input: String) : InputOption { YES("YES"), NO("NO"); @@ -254,23 +287,24 @@ enum class FirstAct(val str: String) { fun fight(firstAct: FirstAct): Float { - val b = 3.0 / aInt * Random.nextFloat() - val c = when { - b < .37 -> .5f - b < .5 -> .4f - b < .63 -> .3f - b < .87 -> .2f - else -> .1f + val b = 3.0 / bullQuality.level * RandomNumbers.nextFloat() + val firstActQuality = when { + b < .37 -> Quality.Awful + b < .5 -> Quality.Poor + b < .63 -> Quality.Fair + b < .87 -> Quality.Good + else -> Quality.Superb } - val t = (10 * c + .2).toInt() - println("THE $firstAct DID A ${quality[t - 1]} JOB.") + val c = firstActQuality.level / 10f + val t = firstActQuality.level + println("THE $firstAct DID A $firstActQuality JOB.") - if (t >= 4) { - if (t == 5) { + if (t >= 4f) { + if (t == 5f) { if (firstAct != FirstAct.toreadores) { - println("$fna OF THE HORSES OF THE $firstAct KILLED.") + println("${fna.asInteger} OF THE HORSES OF THE $firstAct KILLED.") } - println("$fna OF THE $firstAct KILLED.") + println("${fna.asInteger} OF THE $firstAct KILLED.") } else { println( when (fna) { @@ -316,7 +350,7 @@ private fun instructions() { fun intro() { println(" ".repeat(34) + "BULL") println(" ".repeat(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") - repeat(3) { - println() - } + println() + println() + println() } From 0f169d8e0c948b08be616020f13d1225af7a7856 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Sun, 20 Nov 2022 08:57:35 +1100 Subject: [PATCH 7/9] Comments on strange logic behind bullfight.bas --- 17_Bullfight/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/17_Bullfight/README.md b/17_Bullfight/README.md index cf331235..c801b16e 100644 --- a/17_Bullfight/README.md +++ b/17_Bullfight/README.md @@ -27,3 +27,5 @@ http://www.vintage-basic.net/games.html #### Porting Notes (please note any difficulties or challenges in porting here) + +- There is a fundamental assumption in the pre-fight subroutine at line 1610, that the Picadores and Toreadores are more likely to do a bad job (and possibly get killed) with a low-quality bull. This appears to be a mistake in the original code, but should be retained. \ No newline at end of file From c9142a64bdead190224368eb1d1f3e7043550467 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Sun, 20 Nov 2022 09:09:25 +1100 Subject: [PATCH 8/9] Revert edits to bullfight.bas --- 17_Bullfight/bullfight.bas | 140 +++++++++++++++---------------------- 1 file changed, 55 insertions(+), 85 deletions(-) diff --git a/17_Bullfight/bullfight.bas b/17_Bullfight/bullfight.bas index a2aa45b7..32b04b89 100644 --- a/17_Bullfight/bullfight.bas +++ b/17_Bullfight/bullfight.bas @@ -6,25 +6,25 @@ 205 PRINT "DO YOU WANT INSTRUCTIONS"; 206 INPUT Z$ 207 IF Z$="NO" THEN 400 - println("HELLO, ALL YOU BLOODLOVERS AND AFICIONADOS.") - println("HERE IS YOUR BIG CHANCE TO KILL A BULL.") - println() - println("ON EACH PASS OF THE BULL, YOU MAY TRY") - println("0 - VERONICA (DANGEROUS INSIDE MOVE OF THE CAPE)") - println("1 - LESS DANGEROUS OUTSIDE MOVE OF THE CAPE") - println("2 - ORDINARY SWIRL OF THE CAPE.") - println() - println("INSTEAD OF THE ABOVE, YOU MAY TRY TO KILL THE BULL") - println("ON ANY TURN: 4 (OVER THE HORNS), 5 (IN THE CHEST).") - println("BUT IF I WERE YOU,") - println("I WOULDN'T TRY IT BEFORE THE SEVENTH PASS.") - println() - println("THE CROWD WILL DETERMINE WHAT AWARD YOU DESERVE") - println("(POSTHUMOUSLY IF NECESSARY).") - println("THE BRAVER YOU ARE, THE BETTER THE AWARD YOU RECEIVE.") - println() - println("THE BETTER THE JOB THE PICADORES AND TOREADORES DO,") - println("THE BETTER YOUR CHANCES ARE.") +210 PRINT "HELLO, ALL YOU BLOODLOVERS AND AFICIONADOS." +220 PRINT "HERE IS YOUR BIG CHANCE TO KILL A BULL." +230 PRINT +240 PRINT "ON EACH PASS OF THE BULL, YOU MAY TRY" +250 PRINT "0 - VERONICA (DANGEROUS INSIDE MOVE OF THE CAPE)" +260 PRINT "1 - LESS DANGEROUS OUTSIDE MOVE OF THE CAPE" +270 PRINT "2 - ORDINARY SWIRL OF THE CAPE." +280 PRINT +290 PRINT "INSTEAD OF THE ABOVE, YOU MAY TRY TO KILL THE BULL" +300 PRINT "ON ANY TURN: 4 (OVER THE HORNS), 5 (IN THE CHEST)." +310 PRINT "BUT IF I WERE YOU," +320 PRINT "I WOULDN'T TRY IT BEFORE THE SEVENTH PASS." +330 PRINT +340 PRINT "THE CROWD WILL DETERMINE WHAT AWARD YOU DESERVE" +350 PRINT "(POSTHUMOUSLY IF NECESSARY)." +360 PRINT "THE BRAVER YOU ARE, THE BETTER THE AWARD YOU RECEIVE." +370 PRINT +380 PRINT "THE BETTER THE JOB THE PICADORES AND TOREADORES DO," +390 PRINT "THE BETTER YOUR CHANCES ARE." 400 PRINT 410 PRINT 420 D(5)=1 @@ -32,70 +32,55 @@ 450 DIM L$(5) 455 A=INT(RND(1)*5+1) 460 FOR I=1 TO 5 - 463 READ L$(I) +463 READ L$(I) 467 NEXT I 470 DATA "SUPERB","GOOD","FAIR","POOR","AWFUL" 490 PRINT "YOU HAVE DRAWN A ";L$(A);" BULL." 500 IF A>4 THEN 530 - - 510 IF A<2 THEN 550 - 520 GOTO 570 - - 530 PRINT "YOU'RE LUCKY." - 540 GOTO 570 - - 550 PRINT "GOOD LUCK. YOU'LL NEED IT." - 560 PRINT - +510 IF A<2 THEN 550 +520 GOTO 570 +530 PRINT "YOU'RE LUCKY." +540 GOTO 570 +550 PRINT "GOOD LUCK. YOU'LL NEED IT." +560 PRINT 570 PRINT - 590 A$="PICADO" 595 B$="RES" 600 GOSUB 1610 - 610 D(1)=C - 630 A$="TOREAD" 635 B$="ORES" 640 GOSUB 1610 - 650 D(2)=C 660 PRINT 670 PRINT 680 IF Z=1 THEN 1310 - 690 D(3)=D(3)+1 700 PRINT "PASS NUMBER";D(3) 710 IF D(3)<3 THEN 760 - - 720 PRINT "HERE COMES THE BULL. TRY FOR A KILL"; - 730 GOSUB 1930 - 735 IF Z1=1 THEN 1130 - 740 PRINT "CAPE MOVE"; - 750 GOTO 800 -#else - 760 PRINT "THE BULL IS CHARGING AT YOU! YOU ARE THE MATADOR--" - 770 PRINT "DO YOU WANT TO KILL THE BULL"; - 780 GOSUB 1930 - 785 IF Z1=1 THEN 1130 - 790 PRINT "WHAT MOVE DO YOU MAKE WITH THE CAPE"; - +720 PRINT "HERE COMES THE BULL. TRY FOR A KILL"; +730 GOSUB 1930 +735 IF Z1=1 THEN 1130 +740 PRINT "CAPE MOVE"; +750 GOTO 800 +760 PRINT "THE BULL IS CHARGING AT YOU! YOU ARE THE MATADOR--" +770 PRINT "DO YOU WANT TO KILL THE BULL"; +780 GOSUB 1930 +785 IF Z1=1 THEN 1130 +790 PRINT "WHAT MOVE DO YOU MAKE WITH THE CAPE"; 800 INPUT E 810 IF E<>INT(ABS(E)) THEN 830 - 820 IF E<3 THEN 850 - 830 PRINT "DON'T PANIC, YOU IDIOT! PUT DOWN A CORRECT NUMBER" - 840 GOTO 800 - 850 REM - +820 IF E<3 THEN 850 +830 PRINT "DON'T PANIC, YOU IDIOT! PUT DOWN A CORRECT NUMBER" +840 GOTO 800 +850 REM 860 IF E=0 THEN 920 - 870 IF E=1 THEN 900 - 880 M=.5 - 890 GOTO 930 - 900 M=2 - 910 GOTO 930 -#else - 920 M=3 - +870 IF E=1 THEN 900 +880 M=.5 +890 GOTO 930 +900 M=2 +910 GOTO 930 +920 M=3 930 L=L+M 940 F=(6-A+M/10)*RND(1)/((D(1)+D(2)+D(3)/10)*5) 950 IF F<.51 THEN 660 @@ -134,7 +119,6 @@ 1280 GOTO 1320 1290 IF K>.8 THEN 960 1300 GOTO 1260 - 1310 PRINT 1320 PRINT 1330 PRINT @@ -165,51 +149,37 @@ 1580 PRINT 1590 PRINT "ADIOS":PRINT:PRINT:PRINT 1600 GOTO 2030 - 1610 B=3/A*RND(1) 1620 IF B<.37 THEN 1740 1630 IF B<.5 THEN 1720 1640 IF B<.63 THEN 1700 1650 IF B<.87 THEN 1680 - 1660 C=.1 1670 GOTO 1750 - 1680 C=.2 1690 GOTO 1750 - 1700 C=.3 1710 GOTO 1750 - 1720 C=.4 1730 GOTO 1750 - 1740 C=.5 - 1750 T=INT(10*C+.2) 1760 PRINT "THE ";A$;B$;" DID A ";L$(T);" JOB." - 1770 IF 4>T THEN 1900 - 1780 IF 5=T THEN 1870 - 1790 ON FNA(K) GOTO 1830,1850 - - REM Dead code +1780 IF 5=T THEN 1870 +1790 ON FNA(K) GOTO 1830,1850 1800 IF A$="TOREAD" THEN 1820 1810 PRINT "ONE OF THE HORSES OF THE ";A$;B$;" WAS KILLED." 1820 ON FNA(K) GOTO 1830,1850 - - 1830 PRINT "ONE OF THE ";A$;B$;" WAS KILLED." - 1840 GOTO 1900 - - 1850 PRINT "NO ";A$;B$;" WERE KILLED." - 1860 GOTO 1900 - - 1870 IF A$="TOREAD" THEN 1890 - 1880 PRINT FNA(K);"OF THE HORSES OF THE ";A$;B$;" KILLED." - 1890 PRINT FNA(K);"OF THE ";A$;B$;" KILLED." +1830 PRINT "ONE OF THE ";A$;B$;" WAS KILLED." +1840 GOTO 1900 +1850 PRINT "NO ";A$;B$;" WERE KILLED." +1860 GOTO 1900 +1870 IF A$="TOREAD" THEN 1890 +1880 PRINT FNA(K);"OF THE HORSES OF THE ";A$;B$;" KILLED." +1890 PRINT FNA(K);"OF THE ";A$;B$;" KILLED." 1900 PRINT 1910 RETURN - 1920 REM 1930 INPUT A$ 1940 IF A$="YES" THEN 1990 From 372eabc4a133ee1f8319752e12c10120de027ab2 Mon Sep 17 00:00:00 2001 From: Paul Holt Date: Sun, 20 Nov 2022 09:12:23 +1100 Subject: [PATCH 9/9] Revert "Added explicit request for a gradle build submodule" This reverts commit 2d1911ff3d6015bfd9c633400e98d8454a998f34. --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index da9078ed..00000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "basic-computer-games-gradle"] - path = basic-computer-games-gradle - url = https://github.com/pcholt/basic-computer-games-gradle.git