Superhirn, einmal andersherum
Lassen Sie den C 64 Ihre Kombination herausfinden. Nach einem perfekten Algorithmus kann der C 64 Ihre Zahlenfolge in maximal sechs Versuchen berechnen.
Beim Spiel Superhirn geht es darum, einen von einem Q Mitspieler ausgedachten Farbcode zu erraten. Man W probiert verschiedene Farbcodes aus; der Mitspieler gibt nach einer versuchten Kombination Information über deren Richtigkeit.
Es gibt schon einige Superhirn-Programme, die eine Kombination wählen, die dann der menschliche Mitspieler erraten muß.
Superhirn II geht den anderen Weg: Der Mensch denkt sich eine Kombination aus, die dann der Computer erraten muß! Superhirn II findet jede Kombination garantiert (siehe Kasten).
Die Farben werden durch Zahlen symbolisiert. Es gibt sechs»Farbzahlen«, nämlich die Ziffern 1,2,3,4,5und6. Für die Farben gibt es vier Positionen
Bedienungsanleitung:
Geben Sie Superhirn II bitte mit dem MSE ein (Listing 1) und starten Sie es mit »SYS 13312«.
Sie antworten, indem Sie zuerst die Anzahl der richtigen Farbziffern an der richtigen Position eingeben und dann mit »RETURN« abschließen. Dann geben Sie die Anzahl der richtigen Farbziffern an der falschen Position ein und bestätigen wiederum mit »RETURN«.
Superhirn II gibt dann seinen neuen Lösungsvorschlag aus; Sie antworten wieder wie oben. Das Programm ist beendet, wenn
- das Programm die richtige Kombination gefunden hat (es meldet sich mit »OK«)
- oder wenn Sie eine unmögliche Antwort gegeben haben (das Programm meldet sich mit »ERROR«).
Beispiel:
Nehmen wir die Kombination »3436«. Nach Programm-Start beginnt Superhirn II wie üblich mit seiner Startkombination »1234«.
Der Computer hat die »3« richtig als Zahl und Position; die »4« stimmt nur als Zahl.
Also wird eingegeben:
| 1234 | - der Vorschlag des Computers. |
| 1 < RETURN > | - für die richtige »3«. |
| 1 < RETURN > | - für die »4« an falscher Position. |
| Jetzt sucht der Computer einen neuen Lösungsvorschlag. Verfolgen wir die Eingaben bis zum Ende … | |
| 2211 | - der 2. Versuch des Computers. |
| 0 < RETURN > | - keine richtige Position/richtige Ziffer. |
| 0 < RETURN > | - keine falsche Position/richtige Ziffer. |
| 4333 | - der 3. Versuch des Computers. |
| 1 < RETURN > | - für die richtige »3«. |
| 2 < RETURN > | - für die »3« und »4«. |
| 3344 | - der 4. Versuch des Computers. |
| 1 < RETURN > | - diesmal stimmt die erste »3«. |
| 2 < RETURN > | - dafür sind »3« und »4« vertauscht. |
| 3435 | - der 5. Versuch des Computers. |
| 3 < RETURN > | - bis auf die fehlende »6« richtig. |
| 0 < RETURN > | - die »5« ist falsch. |
| 3436 | - der 6. Versuch des Computers. |
| 4 < RETURN > | - die Kombination ist gefunden. |
| OK | - Sie befinden sich wieder im Basic. |
Das Programm kann mit »SYS 13312« wieder gestartet werden.
Hinweise:
Die Eingabe unlogischer Daten führt zur Ausgabe von »ERROR«. Sie haben dann entweder eine offensichtlich falsche Eingabe gemacht (zum Beispiel bei der Eingabe einer »6« für die Anzahl der richtigen Ziffern - es kann ja nur höchstens »4« als korrekte Eingabe vorkommen!) oder eine logisch falsche Eingabe.
Was ist eine logisch falsche Eingabe? Nehmen wir unser Beispiel von oben:
Geben Sie nach dem 6. Versuch des Computers nicht die (richtige!) »4« ein, sondern »0« und nochmal »0«, antwortet Ihnen der Computer mit »ERROR«. Warum?
Nun gibt es einfach keine Ziffernkombination mehr, die allen Ihren Eingaben gerecht werden kann. Folglich müssen Sie einen Eingabe-Fehler gemacht haben.
Geben Sie in unserem Beispiel nach dem 3. Versuch des Computers nicht »1« und »2« (was nach Wahl unserer Ziffernkombination »3436« die einzig korrekte Eingabe ist), sondern »2« und »2«, kann Fehleingabe natürlich nicht miteinem »ERROR« beantwortet werden, weil nämlich jetzt noch Ziffernkombinationen vorhanden sind, die nicht im Widerspruch zu Ihren bis dahin gemachten Eingaben stehen.
Zum Programm:
Den Quelltext des Programms entnehmen Sie Listing 2. Die Eingabe-Routine liest nur das erste Zeichen jeder Zeile - es macht also keinen Unterschied, ob man als Antwort »1« oder »123456« eingibt, da die restlichen Zeichen nicht berücksichtigt werden.
Das Programm ist leicht auf zum Beispiel 10 Positionen erweiterbar - man muß jedoch folgendes beachten: Die Abstände zwischen den Registern POS1,…., CWEISSE müssen vergrößert werden, da möglicherweise neun Versuche nicht zum Ziel führen.
Auch die Anzahl der möglichen Ziffern kann leicht von sechs auf acht erweitert werden. Möchte man mehr als acht Ziffern, muß man mit 16-Bit-Zahlen arbeiten, was größere Umschreibarbeiten zur Folge hat.
Kombinations-Codierung:
Es bleibt noch die Frage, in welcher Art und Weise die Kombinationen gespeichert werden. Nehmen wir dazu doch wieder unsere Kombination aus dem Beispiel, also »3436«.
In POS1, POS2, POS3 und POS4 steht immer die aktuelle Kombination, die der Computer gerade als Lösungsversuch ausgegeben hat.
Ist das Problem gerade bei der Lösung angelangt, dann steht nicht etwa in POS1 die »3«, in POS2 die »4«, in POS3 wieder die »3« und in POS4 die »6« - sondern die Kombination ist folgendermaßen festgehalten:
POS1 - 2 hoch (3-1)
POS2 - 2 hoch (4-1)
POS3 - 2 hoch (3-1)
POS4 - 2 hoch (6-1)
Durch diese Darstellung ist es später leichter möglich, die Anzahl der Schwarzen (= richtige Ziffer/richtige Position) und die Anzahl der Weißen (= richtige Ziffer/falsche Position) zu bestimmen.
Der Lösungsversuch des Computers in der x-ten Runde stehtgenauso codiertin POS1+X, POS2+X, POS3+Xund POS4+X.
(A. Reiser/H. Bauschke/og)Das Programm gibt den ersten Lösungsvorschlag aus. Nach der Eingabe des menschlichen Mitspielers wird eine Ziffernkombination gesucht, die logisch richtig ist in bezug auf alle vorher gemachten Eingaben.
Dabei werden alle Ziffernkombinationen von »1111« bis »6666« getestet.
Ist die aktuelle Ziffernkombination logisch richtig, gibt sie der Computer aus.
Das Programm beginnt bei der nächsten Suche nach der Lösung bei der zuletzt ausgegebenen Ziffernkombination; es muß also nicht wieder bei »1111« anfangen.
Hat der menschliche Gegner nicht mit »4« bei richtiger Position/richtige Farbe geantwortet und ist das Programm bei »6666« angelangt, kann es sich nur um eine falsche Eingabe handeln - es wird »ERROR« ausgegeben.
Wie beurteilt das Programm nun, ob es in seiner Schleife von »1111« bis »6666« gerade bei einer logisch richtigen oder logisch falschen Ziffernkombination ist?
Dazu benutzt der Algorithmus folgenden Trick: Es wird angenommen, daß die zu prüfende Ziffernkombination die richtige ist. Dann werden alle bis dahin getätigten Eingaben mit dieser Kombination verglichen. Es wird also nach der Anzahl der richtigen Ziffer/richtige Position und nach der Anzahl richtige Ziffer/falsche Position gesucht. Das Ergebnis wird festgehalten und mit den Eingaben, die Sie gemacht haben, verglichen.
Stimmen diese Werte sämtlich überein, kann es sich bei der zu prüfenden Kombination um die Lösung handeln - sie muß es aber nicht sein!
Trifft nun das Programm auf eine solche Lösungsmöglichkeit, gibt es diese auch aus.
Ist die Prüfung negativ ausgefallen, das heißt, es gab mindestens eine Abweichung von der tatsächlichen Eingabe des menschlichen Mitspielers, wird in der großen Schleife weitergesucht - so lange, bis die Kombination gefunden ist.
PROGRAMM : SUPERHIRN II 3400 360C ----------------------------------- 3400 : A9 93 20 D2 FF A9 01 8D 42 3408 : 3E 03 8D 52 03 8D 5C 03 8A 3410 : 8D 66 03 8D 70 03 8D 53 3F 3418 : 03 0A 8D 5D 03 0A 8D 67 B5 3420 : 03 0A 8D 71 03 A9 DF A0 F8 3428 : 35 20 1E AB 20 AC 35 C0 28 3430 : FF D0 01 60 4C 3B 35 AD B3 3438 : 52 03 29 20 D0 06 0E 52 74 3440 : 03 4C 3B 35 A9 01 8D 52 5C 3448 : 03 AD 5C 03 29 20 D0 06 7C 3450 : 0E 5C 03 4C 3B 35 A9 01 DD 3458 : 8D 5C 03 AD 66 03 29 20 ED 3460 : D0 06 0E 66 03 4C 3B 35 6E 3468 : A9 01 8D 66 03 AD 70 03 27 3470 : 29 20 D0 06 0E 70 03 4C A7 3478 : 3B 35 A9 6B A0 A3 20 1E 09 3480 : AB 60 A9 00 9D 84 03 AD 2B 3488 : 52 03 3D 52 03 F0 03 FE B7 3490 : 84 03 AD 5C 03 3D 5C 03 1E 3498 : F0 03 FE 84 03 AD 66 03 97 34A0 : 3D 66 03 F0 03 FE 84 03 2F 34A8 : AD 70 03 3D 70 03 F0 03 DF 34B0 : FE 84 03 60 AD 52 03 8D 52 34B8 : 3F 03 AD 5C 03 8D 40 03 13 34C0 : AD 66 03 8D 41 03 AD 70 D7 34C8 : 03 8D 42 03 BD 52 03 8D 18 34D0 : 43 03 BD 5C 03 8D 44 03 43 34D8 : BD 66 03 8D 45 03 BD 70 7F 34E0 : 03 8D 46 03 A9 00 8D 49 FF 34E8 : 03 A0 06 A9 00 8D 47 03 82 34F0 : 8D 48 03 8A 48 A9 03 AA E7 34F8 : 5E 3F 03 90 03 EE 47 03 94 3500 : 5E 43 03 90 03 EE 48 03 A2 3508 : CA 10 ED 68 AA AD 47 03 9E 3510 : 38 ED 48 03 30 0D AD 49 66 3518 : 03 18 6D 48 03 8D 49 03 54 3520 : 4C 2D 35 AD 49 03 18 6D EE 3528 : 47 03 8D 49 03 88 D0 BB AD 3530 : AD 49 03 38 FD 84 03 9D 95 3538 : 98 03 60 AE 3E 03 20 82 C1 3540 : 34 BD 84 03 DD 7A 03 F0 74 3548 : 03 4C 37 34 20 B4 34 BD BA 3550 : 98 03 DD 8E 03 F0 03 4C 0F 3558 : 37 34 CA D0 E1 AE 3E 03 08 3560 : E8 AD 52 03 9D 52 03 8D A7 3568 : 43 03 AD 5C 03 9D 5C 03 B8 3570 : 8D 44 03 AD 66 03 9D 66 58 3578 : 03 8D 45 03 AD 70 03 9D 99 3580 : 70 03 8D 46 03 A0 00 A9 27 3588 : 00 AA 18 C8 B9 42 03 4A 4B 3590 : E8 90 FC 8A 18 69 30 20 1F 3598 : D2 FF C0 04 D0 E9 EE 3E AF 35A0 : 03 20 AC 35 C0 FF D0 01 D6 35A8 : 60 4C 37 34 A9 0D 20 D2 AC 35B0 : FF 20 CF FF AE 3E 03 38 0C 35B8 : E9 30 C9 04 D0 0A A9 64 79 35C0 : A0 A3 20 1E AB A0 FF 60 7E 35C8 : 9D 7A 03 A9 0D 20 D2 FF B5 35D0 : 20 CF FF 38 E9 30 9D 8E 92 35D8 : 03 A9 0D 20 D2 FF 60 31 08 35E0 : 32 33 34 00 A9 00 85 6A 3E 35E8 : 85 6C A9 04 85 6B A9 34 51 35F0 : 85 6D A0 00 B1 6A 91 6C E1 35F8 : C8 D0 F9 A5 6B C9 07 F0 5E 3600 : 07 E6 6B E6 6D 18 90 EA E2 3608 : 4C 00 34 FF 17
100 sys32768 110 .opt oo,p 120 *= $3400 121 ; 122 ; variablen-deklaration 123 ; 125 alt = $6a ; zeropage adressen fuer 126 neu = $6c ; verschiebe-routine 130 chrout = $ffd2 140 chrin = $ffcf 150 strout = $ab1e 160 pos1 = 850 ; speicher fuer 170 pos2 = 860 ; kombinationen 180 pos3 = 870 190 pos4 = 880 200 schwarze = 890 ; eingaben mitspieler 210 cschwarze = 900 ; errechnete eingaben 220 weisse = 910 ; ( siehe algorithmus ) 230 cweisse = 920 ; 240 runde = 830 245 ; diverse hilfsregister 250 cpos1 = 831 260 cpos2 = 832 270 cpos3 = 833 280 cpos4 = 834 290 cv1 = 835 300 cv2 = 836 310 cv3 = 837 320 cv4 = 838 330 h1 = 839 340 h2 = 840 360 min = 841 370 ; 372 ; programm-start 374 ; 380 lda #147 390 jsr chrout ; bildschirm loeschen 470 lda #1 475 sta runde ; runde initialisiert 480 sta pos1:sta pos2:sta pos3:sta pos4 ; schleife initialisiert auf '1111' 485 ; 486 ; 1. versuch '1234' abspeichern und ausgeben 487 ; 490 sta pos1+1 500 asl a :sta pos2+1 510 asl a :sta pos3+1 520 asl a :sta pos4+1 540 lda #<text 550 ldy #>text 560 jsr strout 570 jsr antwort 572 cpy #$ff ; kombination gefunden ja/nein 574 bne l0 ; nein - also suchen 576 rts ; ja - zurueck ins basic 580 l0 jmp liloop 600 ; 610 ; grosse schleife - '1111' bis '6666' 620 ; 640 grloop lda pos1 650 and #%00100000 660 bne massn1 670 asl pos1 680 jmp liloop 690 massn1 lda #1 700 sta pos1 710 test2 lda pos2 720 and #%00100000 730 bne massn2 740 asl pos2 750 jmp liloop 760 massn2 lda #1 770 sta pos2 780 test3 lda pos3 790 and #%00100000 800 bne massn3 810 asl pos3 820 jmp liloop 830 massn3 lda #1 840 sta pos3 850 test4 lda pos4 860 and #%00100000 870 bne massn4 880 asl pos4 890 jmp liloop 900 massn4 lda #$6b:ldy #$a3 ; kombination nicht gefunden 910 jsr strout ; 'error' ausgeben 930 rts ; und zurueck ins basic. 932 ; 933 ; unterprogramm anzahl schwarze ermitteln 934 ; 940 blacks lda #0 950 sta cschwarze,x 960 pos1v lda pos1 970 and pos1,x 980 beq pos2v 990 inc cschwarze,x 1000 pos2v lda pos2 1010 and pos2,x 1020 beq pos3v 1030 inc cschwarze,x 1040 pos3v lda pos3 1050 and pos3,x 1060 beq pos4v 1070 inc cschwarze,x 1080 pos4v lda pos4 1090 and pos4,x 1100 beq bfin 1110 inc cschwarze,x 1120 bfin rts 1122 ; 1124 ; unterprogramm anzahl weisse ermitteln 1126 ; 1130 whites lda pos1 1140 sta cpos1 1150 lda pos2 1160 sta cpos2 1170 lda pos3 1180 sta cpos3 1190 lda pos4 1200 sta cpos4 1210 lda pos1,x 1220 sta cv1 1230 lda pos2,x 1240 sta cv2 1250 lda pos3,x 1260 sta cv3 1270 lda pos4,x 1280 sta cv4 1290 lda #0 1300 sta min 1310 ldy #6 1330 los lda #0 1340 sta h1 1350 sta h2 1400 txa:pha:lda #3:tax 1410 l1 lsr cpos1,x 1420 bcc l2 1430 inc h1 1440 l2 lsr cv1,x 1450 bcc l3 1460 inc h2 1470 l3 dex 1480 bpl l1 1490 pla:tax 1600 minfind lda h1 1610 sec 1620 sbc h2 1630 bmi h2gross 1640 h1gross lda min 1650 clc 1660 adc h2 1670 sta min 1680 jmp ykleiner 1690 h2gross lda min 1700 clc 1710 adc h1 1720 sta min 1730 ykleiner dey 1740 bne los 1750 lda min 1760 sec 1770 sbc cschwarze,x 1780 sta cweisse,x 1790 wfin rts 1792 ; 1794 ; kleine schleife - kombination logisch-richtig (j/n) 1796 ; 1800 liloop ldx runde 1810 listart jsr blacks 1820 lda cschwarze,x 1830 cmp schwarze,x 1840 beq l4 1845 jmp grloop 1850 l4 jsr whites 1860 lda cweisse,x 1870 cmp weisse,x 1880 beq l5 1885 jmp grloop 1890 l5 dex 1900 bne listart 1902 ; 1904 ; logisch-richtige kombination ausgeben 1906 ; 1910 ldx runde 1920 inx 1930 lda pos1 1940 sta pos1,x:sta cv1 1950 lda pos2 1960 sta pos2,x:sta cv2 1970 lda pos3 1980 sta pos3,x:sta cv3 1990 lda pos4 2000 sta pos4,x:sta cv4 2080 ldy #0 2090 l6 lda #0:tax 2095 clc:iny 2100 lda cv1-1,y 2110 l7 lsr a 2120 inx 2130 bcc l7 2140 txa:clc:adc #$30 2150 jsr chrout 2160 cpy #4 2170 bne l6 2190 inc runde 2200 jsr antwort 2202 cpy #$ff 2204 bne l8 2206 rts 2210 l8 jmp grloop 2212 ; 2214 ; unterprogramm antwort holen 2216 ; 2220 antwort lda #$0d:jsr chrout 2230 jsr chrin 2240 ldx runde 2250 sec:sbc #$30 2252 cmp #4 2254 bne l9 2256 lda #$64:ldy #$a3:jsr strout 2258 ldy #$ff 2259 rts 2260 l9 sta schwarze,x:lda #$0d:jsr chrout 2270 jsr chrin 2280 sec:sbc #$30:sta weisse,x 2290 lda #$0d 2300 jsr chrout:rts 2310 ; 2311 ; '1234' 2312 ; 2320 text .asc "1234" : .byt 0 3000 ; 3005 ; verschieben nach $3400 3010 ; 3100 lda #0:sta alt:sta neu 3110 lda #$04:sta alt+1 3120 lda #$34:sta neu+1 3130 l10 ldy #0 3140 l11 lda (alt),y:sta (neu),y 3170 iny 3180 bne l11 3190 lda alt+1 3200 cmp #$07 3210 beq aufgehts 3220 inc alt+1:inc neu+1 3230 clc:bcc l10 3240 aufgehts jmp $3400 ; programm-startAnmerkung: Ursprünglich war das Programm als »Bildschirmseite« konzipiert. Die Verschieberoutine ab Zeile 3000 wurde benötigt, um das Programm aus dem Bildschirmspeicher an seinen »Arbeitsplatz« zu bringen.