02-08-2025, 08:55 PM
Mystery Mania is a clever little logic problem generator I found in COMPUTE! magazine back in 1987 https://archive.org/details/1987-12-comp...ew=theater.
Your job is solve a murder mystery with the given clues. It can generate 160005 (seed * level) puzzles. If you like logic problems, this is for you.
I tried to keep the program as close to original as possible, but I made a few changes to make it more usable. I've attached a version that is closer to the original for posterity.
Change log:
If you want to have some fun, try feeding the puzzle to an AI like deepseek-r1. It responses can get hilariously long and then its confidently wrong.
Your job is solve a murder mystery with the given clues. It can generate 160005 (seed * level) puzzles. If you like logic problems, this is for you.
I tried to keep the program as close to original as possible, but I made a few changes to make it more usable. I've attached a version that is closer to the original for posterity.
Change log:
- Made it SCREEN 12 to keep text from scrolling off the screen.
- Switched hard copy (to your printer) to print to file.
If you want to have some fun, try feeding the puzzle to an AI like deepseek-r1. It responses can get hilariously long and then its confidently wrong.
Code: (Select All)
10 ' Copyright 1987 COMPUTE! Publications, Inc. - All Rights Reserved
20 DEFINT A-Z: DIM P$(9, 10), M$(5, 6), CL$(13), CG$(13), F$(4), MP$(2), MW$(2)
30 SCREEN 12: KEY OFF: COLOR 15, 1: CLS
40 PRINT SPC(40);: SW = POS(0) + 39: CLS: S$ = "Copyright 1987 COMPUTE! Publ., Inc.": GOSUB 1460: S$ = "All rights reserved": GOSUB 1460: PRINT: PRINT
50 PRINT: PRINT: S$ = "PRESENTING ": GOSUB 1460: PRINT: S$ = CHR$(201) + STRING$(15, 205) + CHR$(187): GOSUB 1460: S$ = CHR$(186) + " MYSTERY MANIA " + CHR$(186): GOSUB 1460: S$ = CHR$(200) + STRING$(15, 205) + CHR$(188): GOSUB 1460
60 PRINT: S$ = "The game that generates murder mystery": GOSUB 1460: S$ = "logic problems for you to solve": GOSUB 1460: S$ = "Press space bar to continue. ": GOSUB 1470
70 S$ = "This game can generate 32001 different mysteries, numbered 0 to 32000. You can play the same game repeatedly by choosing the same number each time you play, or you can choose a different mystery each time.": GOSUB 1360
80 PRINT: INPUT "Which mystery story (0-32000) "; M: IF M < 0 OR M > 32000 THEN PRINT "IN VALID ANSWER !": GOTO 80
90 RANDOMIZE M
100 FOR X = 0 TO M MOD 99: Y = RND(1): NEXT X
110 PRINT: S$ = "There are five difficulty levels, from 1 to 5. Level 1 is easy, while level five would keep Sherlock Holmes busy for a while. The different levels actually generate different games for the same number above. ": GOSUB 1360
120 PRINT: PRINT "Difficulty level (1-5)?";
130 S$ = INKEY$: IF S$ < "1" OR S$ > "5" THEN 130
140 PRINT S$: L = VAL(S$): GOSUB 1530
150 PRINT: PRINT "Do you want save story to text file ("; TF$; ") (Y/N)?";: GOSUB 1430: PR = YN: PRINT Y$
160 CLS
170 ' Read in data
180 FOR X = 0 TO 9: FOR Y = 0 TO 10: READ P$(X, Y): NEXT Y: NEXT X
190 FOR X = 0 TO 2: READ MP$(X): NEXT X: FOR X = 0 TO 2: READ MW$(X): NEXT X
200 ' Generate suspect names
210 A = INT(RND(1) * 11): B = INT(RND(1) * 11): V$ = P$(0, A) + " " + P$(1, B): P$(0, A) = "": P$(1, B) = ""
220 FOR X = 1 TO 5
230 A = INT(RND(1) * 11): A$ = P$(0, A): P$(0, A) = "": IF A$ = "" THEN 230
240 B = INT(RND(1) * 11): B$ = P$(1, B): P$(1, B) = "": IF B$ = "" THEN 240
250 M$(0, X) = A$ + " " + B$
260 NEXT X
270 FOR X = 0 TO 4: F$(X) = M$(0, X + 1): NEXT X
280 FOR X = 0 TO 9: A = INT(RND(1) * 5): B = INT(RND(1) * 5): SWAP F$(A), F$(B): NEXT X
290 S$ = "Six men, " + V$ + ", " + F$(0) + ", " + F$(1) + ", " + F$(2) + ", " + F$(3) + ", and " + F$(4) + " were in " + MP$(INT(RND(1) * 3)) + " together, Suddenly, the lights went out. ": GOSUB 1360
300 S$ = "When the lights came back on, " + V$ + " was found " + MW$(INT(RND(1) * 3)) + ". ": GOSUB 1360
310 PRINT: S$ = "The other detectives have investigated. They have questioned the suspects, the witnesses, and people who know the suspects. They have collected physical evidence (hair samples, fiber samples, etc.) from the crime scene.": GOSUB 1360
320 ' Generate suspect data
330 FOR P = 1 TO 5
340 A = INT(RND(1) * 8 + 2): IF P$(A, 0) = "" THEN 340
350 M$(P, 0) = P$(A, 0): P$(A, 0) = ""
360 FOR Y = 1 TO 5
370 B = INT(RND(1) * 9) + 1: IF P$(A, B) = "" THEN 370
380 M$(P, Y) = P$(A, B): P$(A, B) = ""
390 NEXT Y
400 M$(P, 6) = P$(A, 10)
410 NEXT P
420 PRINT: S$ = "They have collected 14 clues, but have not been able to solve the crime. Therefore, they have called in the city's greatest homicide detective. That's YOU! You will now be given the clues, and must solve the murder.": GOSUB 1360
430 ' Generate clues
440 K$ = M$(0, 6 - L + (L = 3) - (L = 4)): C$ = M$(4, 0) + " " + M$(4, 6 - L + (L = 3) - (L = 4))
450 CL$(0) = M$(0, 1) + " " + M$(2, 0) + " " + M$(2, 1)
460 CL$(1) = M$(0, 2) + " " + M$(5, 0) + " " + M$(5, 2)
470 CL$(2) = M$(0, 3) + " " + M$(1, 0) + " " + M$(1, 3)
480 CL$(3) = M$(0, 4) + " " + M$(3, 0) + " " + M$(3, 4)
490 C1 = (RND(1) < .5): IF C1 <> 0 OR L = 1 THEN CL$(4) = M$(0, 5) + " " + M$(1, 0) + " " + M$(1, 5) ELSE CL$(4) = M$(0, 5) + " " + M$(4, 0) + " " + M$(4, 5)
500 T$ = "The suspect who ": N$ = " is not the one who "
510 A1$ = M$(2, 0): A2$ = M$(2, 4): B1$ = M$(4, 0): B2$ = M$(4, 4): GOSUB 1500
520 CL$(5) = T$ + A1$ + " " + A2$ + " " + B1$ + " " + B2$
530 A1$ = M$(1, 0): A2$ = M$(1, 4): IF RND(1) < .5 THEN C1$ = N$ + M$(5, 0) + " " + M$(5, 2): GOTO 560
540 Bl$ = M$(5, 0): B2$ = M$(5, 4)
550 C1$ = " " + B1$ + " " + B2$
560 CL$(6) = T$ + A1$ + " " + A2$ + C1$
570 A1$ = M$(1, 0): A2$ = M$(1, 4): B1$ = M$(2, 0): B2$ = M$(2, 4): GOSUB 1500
580 NF = 0: GOSUB 1510: CL$(7) = Q$
590 A1$ = M$(1, 0): A2$ = M$(1, 2): B1$ = M$(2, 0): B2$ = M$(2, 2): GOSUB 1500
600 GOSUB 1510: CL$(8) = Q$
610 A1$ = M$(2, 0): A2$ = M$(2, 2): B1$ = M$(4, 0): B2$ = M$(4, 2): GOSUB 1500
620 GOSUB 1510: CL$(9) = Q$
630 A1$ = M$(1, 0): A2$ = M$(1, 5): B1$ = M$(4, 0): B2$ = M$(4, 5): GOSUB 1500
640 GOSUB 1510: CL$(10) = Q$
650 A1$ = M$(1, 0): A2$ = M$(1, 1): B1$ = M$(4, 0): B2$ = M$(4, 3): GOSUB 1500
660 NF = 1: GOSUB 1510: CL$(11) = Q$
670 A1$ = M$(2, 0): A2$ = M$(2, 5): B1$ = M$(3, 0): B2$ = M$(3, 2): GOSUB 1500
680 GOSUB 1510: CL$(12) = Q$
690 CL$(13) = "The murderer " + C$: S$ = "Press space bar to see clues.": GOSUB 1490
700 ' Output clues
710 FOR X = 0 TO 13: CG$(X) = CL$(X): NEXT X
720 FOR X = 0 TO 25: A = INT(RND(1) * 14): B = INT(RND(1) * 14): SWAP CG$(A), CG$(B): NEXT X
730 S$ = "No two suspects have the same " + M$(1, 6) + ", " + M$(2, 6) + ", " + M$(3, 6) + ", " + M$(4, 6) + " or " + M$(5, 6) + ".": GOSUB 1360
740 FOR X = 0 TO 6: S$ = CG$(X) + ".": GOSUB 1360: PRINT: NEXT X
750 S$ = "Press space bar to continue. ": GOSUB 1490
760 FOR X = 7 TO 13: S$ = CG$(X) + ".": GOSUB 1360: PRINT: NEXT X
770 S$ = "Press space bar to make an arrest. ": GOSUB 1490
780 ' Get player's solution
790 H = 0: PR = 0: CLS: PRINT: PRINT " You may now": PRINT
800 FOR X = 0 TO 4: PRINT MID$(STR$(X + 1), 2, 1); ") Arrest "; F$(X): NEXT X
810 PRINT "6) Quit without seeing solution": PRINT "7) See solution to mystery"
820 IF L > 1 THEN PRINT "8) Get a hint"
830 PRINT: PRINT "Select number of your choice, ";
840 Y$ = INKEY$: IF Y$ < "1" OR Y$ > "8" THEN 840
850 IF L = 1 AND Y$ = "8" THEN 840
860 PRINT Y$: V = VAL(Y$): PRINT
870 IF V = 6 THEN S$ = "Ending game. This was mystery #" + STR$(M) + ". Make a note of this so you can come back to this game later if you like.": GOSUB 1360: GOTO 1230
880 IF V = 7 THEN 940
890 IF V = 8 THEN H = 1: GOTO 940
900 IF F$(V - 1) = K$ THEN S$ = "Correct! Congratulations. You have been promoted to chief of police. ": GOSUB 1360: GOTO 1230
910 S$ = "Sorry, you've arrested the wrong suspect. Do you want to see the correct solution (Y/N)?": GOSUB 1360
920 GOSUB 1430: IF YN = 0 THEN 1230
930 ' Explain solution and give hints
940 PR = 0: PRINT: S$ = "Do you want save explanation to text file (Y/N)?": GOSUB 1360: GOSUB 1430: PR = YN
950 CLS: IF PR THEN S$ = "-----------Explanation------------": GOSUB 1360
960 S$ = CL$(4) + ". ": IF C1 <> 0 OR L = 1 THEN S$ = S$ + " " + CL$(10) + ". Therefore, " + M$(0, 5) + " " + M$(4, 0) + " " + M$(4, 5) + ". "
970 GOSUB 1360
980 IF L = 1 THEN S$ = CL$(13) + ", so " + K$ + " is the murderer.": GOSUB 1360: GOTO 1230
990 S$ = CL$(13) + ", so " + M$(0, 5) + " is not the murderer.": GOSUB 1360
1000 IF H = 1 THEN PRINT: PRINT "Want another hint (Y/N) ?";: GOSUB 1430: PRINT Y$: IF YN = 0 THEN 790
1010 S$ = CL$(5) + ". ": GOSUB 1360: S$ = CL$(7) + ". ": GOSUB 1360: S$ = CL$(6) + ". ": GOSUB 1360: S$ = "Therefore, one suspect " + M$(2, 0) + " " + M$(2, 4) + ", " + M$(4, 0) + " " + M$(4, 4) + ", " + M$(1, 0) + " " + M$(1, 4) + ", and " + C1$ + ".": GOSUB 1360
1020 S$ = "But " + CL$(0) + ", " + CL$(1) + ", " + CL$(2) + ", and " + M$(0, 5) + " " + M$(4, 0) + " " + M$(4, 5) + ". ": GOSUB 1360
1030 S$ = "Press space bar to contiue.": GOSUB 1490
1040 S$ = "Therefore, that one suspect is " + M$(0, 4) + ".": GOSUB 1360
1050 IF L = 2 THEN S$ = "Since " + M$(0, 4) + " " + M$(4, 0) + " " + M$(4, 4) + ", he is the murderer.": GOSUB 1360: GOTO 1230
1060 S$ = "Since " + M$(0, 4) + " " + M$(4, 0) + " " + M$(4, 4) + ", he is not the murderer.": GOSUB 1360
1070 IF H = 1 THEN PRINT "Want another hint (Y/N)?";: GOSUB 1430: PRINT Y$: IF YN = 0 THEN 790
1080 S$ = CL$(8) + ". " + CL$(9) + ".": GOSUB 1360: S$ = "Therefore, one suspect " + M$(1, 0) + " " + M$(1, 2) + ", " + M$(2, 0) + " " + M$(2, 2) + ", and " + M$(4, 0) + " " + M$(4, 2) + ".": GOSUB 1360
1090 S$ = CL$(0) + ", " + CL$(2) + ", " + M$(0, 5) + " " + M$(4, 0) + " " + M$(4, 5) + ", and " + M$(0, 4) + " " + M$(4, 0) + " " + M$(4, 4) + ".": GOSUB 1360: S$ = "Therefore, that one suspect is " + M$(0, 2) + ". ": GOSUB 1360
1100 IF L = 3 THEN S$ = "Since " + M$(0, 2) + " " + M$(4, 0) + " " + M$(4, 2) + ", he is the murderer. ": GOSUB 1360: GOTO 1230
1110 S$ = "Since " + M$(0, 2) + " " + M$(4, 0) + " " + M$(4, 2) + ", he is not the murderer.": GOSUB 1360
1120 S$ = "Press space bar to continue. ": GOSUB 1490
1130 IF H = 1 THEN PRINT "Want another hint (Y/N)?";: GOSUB 1430: PRINT Y$: IF YN = 0 THEN 790
1140 IF C1 THEN S$ = CL$(4) + "." ELSE S$ = CL$(10) + ". " + CL$(4) + ". Therefore, " + M$(0, 5) + " " + M$(1, 0) + " " + M$(1, 5) + "."
1150 GOSUB 1360
1160 S$ = CL$(2) + ", " + M$(0, 4) + " " + M$(1, 0) + " " + M$(1, 4) + ", " + M$(0, 2) + " " + M$(1, 0) + " " + M$(1, 2) + ".": GOSUB 1360: S$ = "Therefore, " + M$(0, 1) + " is the one who " + M$(1, 0) + " " + M$(1, 1) + ".": GOSUB 1360
1170 S$ = "This means that " + M$(0, 1) + " is not the suspect who " + M$(4, 0) + " " + M$(4, 3) + ".": GOSUB 1360
1180 S$ = "Since " + M$(0, 5) + " " + M$(4, 0) + " " + M$(4, 5) + ", " + M$(0, 4) + " " + M$(4, 0) + " " + M$(4, 4) + ", and " + M$(0, 2) + " " + M$(4, 0) + " " + M$(4, 2) + ", " + M$(0, 3) + " must be the one who " + M$(4, 0) + " " + M$(4, 3) + ".": GOSUB 1360
1190 IF L = 4 THEN S$ = "Since the murderer " + C$ + ", " + K$ + "is the murderer. ": GOSUB 1360: GOTO 1230
1200 S$ = "Since the murderer " + C$ + ", " + M$(0, 3) + " is not the murderer. ": GOSUB 1360
1210 IF H = 1 THEN PRINT "Want another clue (Y/N)?";: GOSUB 1430: PRINT Y$: IF YN = 0 THEN 790
1220 S$ = "By process of elimination, " + K$ + " is the murderer. ": GOSUB 1360
1230 PRINT: PRINT "Do you want to play another game (Y/N)?": GOSUB 1430: IF YN = 1 THEN RUN ELSE PRINT: END
1240 DATA Bill,David,John,Tom,Fred,Larry,Brian,Jim,Robert,Jack,Marty
1250 DATA Fox,Martin,Smith,Jones,Harrison,Craig,Davis,Edison,Brown,Stevenson,Alberts
1260 DATA has,black hair,no hair,red hair,blond hair,brown hair,white hair,gray hair,"","",hair color
1270 DATA was wearing,a red shirt,an orange shirt,a yellow shirt,a green shirt,a blue shirt,a purple shirt,a white shirt,a black shirt,"",color shirt
1280 DATA owns,a red car,an orange car,a yellow car,a green car,a blue car,a purple car,a white car,a black car,a silver car,color car
1290 DATA is,5 feet tall,5 feet 3 inches tall,5 feet 6 inches tall,5 feet 9 inches tall,6 feet tall,6 feet 3 inches tall,"","","",height
1300 DATA weighs,140 pounds,150 pounds,160 pounds,170 pounds,180 pounds,190 pounds,200 pounds,210 pounds,220 pounds,weight
1310 DATA was wearing,red shoes,white shoes,brown shoes,black shoes,tan shoes,blue shoes,orange shoes,"","",color shoes
1320 DATA has a wife named,Sue,Joyce,Mary,Betty,Pam,Cathy,Jill,Judy,Sally,wife's first name
1330 DATA was carrying,a red umbrella,an orange umbrella,a yellow umbrella,a green umbrella,a purple umbrella,a white umbrella,a black umbrella,"","",color umbrella
1340 DATA a restaurant,an elevator,a library,stabbed,strangled,shot
1350 ' Print S$ to screen and printer
1360 P = INSTR(S$, " "): IF P = 0 THEN 1400
1370 A1$ = LEFT$(S$, P): S$ = MID$(S$, P + 1)
1380 PRINT A1$;: IF PR THEN OPEN TF$ FOR APPEND AS #1: PRINT #1, A1$;: CLOSE #1
1390 GOTO 1360
1400 PRINT S$: IF PR THEN OPEN TF$ FOR APPEND AS #1: PRINT #1, S$: CLOSE #1
1410 RETURN
1420 ' Get yes/no response
1430 Y$ = INKEY$: IF Y$ <> "Y" AND Y$ <> "y" AND Y$ <> "N" AND Y$ <> "n" THEN 1430
1440 YN = 0: IF Y$ = "Y" OR Y$ = "y" THEN YN = 1
1450 RETURN
1460 PRINT TAB((SW - LEN(S$)) / 2); S$: RETURN
1470 LOCATE 23, 1: GOSUB 1460
1480 IF INKEY$ <> " " THEN 1480 ELSE CLS: RETURN
1490 LOCATE 24, 1: PRINT TAB((SW - LEN(B$)) / 2); S$: GOTO 1480
1500 IF RND(1) < .5 THEN SWAP A1$, B1$: SWAP A2$, B2$: RETURN ELSE RETURN
1510 N$ = " ": IF NF THEN N$ = " is not the one who "
1520 Q$ = T$ + A1$ + " " + A2$ + N$ + B1$ + " " + B2$: RETURN
1530 TF$ = "Mystery_" + _TRIM$(STR$(M)) + "_" + _TRIM$(STR$(L)) + ".txt": RETURN
2D physics engine https://github.com/mechatronic3000/fzxNGN
Untitled Rouge-like https://github.com/mechatronic3000/Untitled-Rougelike
QB Pool https://github.com/mechatronic3000/QBPool
Untitled Rouge-like https://github.com/mechatronic3000/Untitled-Rougelike
QB Pool https://github.com/mechatronic3000/QBPool