; ============================================================================== ; FORTUNE MIND CODE - MASM32 / CP1251 ; Algorithmic Oracle Logic, String Assembly & Student Grade Decision Engine ; ============================================================================== .code ; StrLen: Returns string length in EAX FortuneStrLen PROC uses esi strPtr:DWORD mov esi, strPtr xor eax, eax test esi, esi jz @F fortune_strlen_loop: cmp BYTE PTR [esi+eax], 0 je @F inc eax jmp fortune_strlen_loop @@: ret FortuneStrLen ENDP ; StrCat: Appends src to dst, returns new end pointer in EAX FortuneStrCat PROC uses esi edi dst:DWORD, src:DWORD mov edi, dst test edi, edi jz fortune_strcat_done xor eax, eax mov ecx, -1 repne scasb dec edi mov esi, src test esi, esi jz fortune_strcat_ret fortune_strcat_copy: lodsb stosb test al, al jnz fortune_strcat_copy dec edi fortune_strcat_ret: mov eax, edi fortune_strcat_done: ret FortuneStrCat ENDP ; SubStrI3D: Case-insensitive substring search for CP1251 SubStrI3D PROC uses ebx esi edi hHaystack:DWORD, hNeedle:DWORD mov esi, hHaystack mov edi, hNeedle test esi, esi jz substr_fail test edi, edi jz substr_fail substr_outer: mov al, [esi] test al, al jz substr_fail push esi push edi substr_inner: mov al, [esi] mov bl, [edi] test bl, bl jz substr_found test al, al jz substr_next_outer ; Lowercase compare cmp al, "A" jb @F cmp al, "Z" ja @F add al, 32 @@: cmp al, 192 ; CP1251 А..Я jb @F cmp al, 223 ja @F add al, 32 @@: cmp bl, "A" jb @F cmp bl, "Z" ja @F add bl, 32 @@: cmp bl, 192 jb @F cmp bl, 223 ja @F add bl, 32 @@: cmp al, bl jne substr_next_outer inc esi inc edi jmp substr_inner substr_next_outer: pop edi pop esi inc esi jmp substr_outer substr_found: pop edi pop esi mov eax, 1 ret substr_fail: xor eax, eax ret SubStrI3D ENDP ; InitFortuneMindState3D: Clears buffers and sets up defaults InitFortuneMindState3D PROC uses esi edi mov fortuneSubMode3D, FORTUNE_SUBMODE_MENU mov fortuneCardsDrawn3D, 0 mov studentDone3D, 0 mov studentField3D, 0 mov studentChoice3D, 0 ; Setup default student name if empty cmp studentName3D[0], 0 jne @F lea edi, studentName3D lea esi, strDefaultStudentName fortune_copy_def_name: lodsb stosb test al, al jnz fortune_copy_def_name invoke FortuneStrLen, OFFSET studentName3D mov studentNameLen3D, eax @@: cmp studentYear3D[0], 0 jne @F lea edi, studentYear3D lea esi, strDefaultStudentYear fortune_copy_def_year: lodsb stosb test al, al jnz fortune_copy_def_year invoke FortuneStrLen, OFFSET studentYear3D mov studentYearLen3D, eax @@: ret InitFortuneMindState3D ENDP ; DetectTopic3D: Scans question for keywords ; Returns: 0=General, 1=Casino, 2=Love, 3=Study, 4=Future DetectTopic3D PROC uses ebx esi edi qStr:DWORD mov esi, qStr test esi, esi jz topic_general ; Simple substring check for Russian CP1251 keywords ; Check Casino: "покер", "деньг", "банк", "ставк", "казино" invoke SubStrI3D, esi, OFFSET kwPoker test eax, eax jnz topic_casino invoke SubStrI3D, esi, OFFSET kwMoney test eax, eax jnz topic_casino invoke SubStrI3D, esi, OFFSET kwBank test eax, eax jnz topic_casino invoke SubStrI3D, esi, OFFSET kwBet test eax, eax jnz topic_casino invoke SubStrI3D, esi, OFFSET kwCasino test eax, eax jnz topic_casino invoke SubStrI3D, esi, OFFSET kwWin test eax, eax jnz topic_casino invoke SubStrI3D, esi, OFFSET kwRoulette test eax, eax jnz topic_casino ; Check Love: "любов", "девушк", "парен", "чувств", "отношен" invoke SubStrI3D, esi, OFFSET kwLove test eax, eax jnz topic_love invoke SubStrI3D, esi, OFFSET kwGirl test eax, eax jnz topic_love invoke SubStrI3D, esi, OFFSET kwBoy test eax, eax jnz topic_love invoke SubStrI3D, esi, OFFSET kwRel test eax, eax jnz topic_love ; Check Study: "учеб", "экзамен", "сесси", "балл", "оценк", "лаб" invoke SubStrI3D, esi, OFFSET kwStudy test eax, eax jnz topic_study invoke SubStrI3D, esi, OFFSET kwExam test eax, eax jnz topic_study invoke SubStrI3D, esi, OFFSET kwSession test eax, eax jnz topic_study invoke SubStrI3D, esi, OFFSET kwScore test eax, eax jnz topic_study invoke SubStrI3D, esi, OFFSET kwGrade test eax, eax jnz topic_study ; Check Future: "будущ", "судьб", "выбор", "стоит ли", "что ждет" invoke SubStrI3D, esi, OFFSET kwFuture test eax, eax jnz topic_future invoke SubStrI3D, esi, OFFSET kwFate test eax, eax jnz topic_future invoke SubStrI3D, esi, OFFSET kwChoice test eax, eax jnz topic_future topic_general: xor eax, eax ret topic_casino: mov eax, 1 ret topic_love: mov eax, 2 ret topic_study: mov eax, 3 ret topic_future: mov eax, 4 ret DetectTopic3D ENDP ; GenerateTarotReadingMind3D: Builds full 3-card reading in fortuneAnswer3D GenerateTarotReadingMind3D PROC uses ebx esi edi local c1:DWORD, c2:DWORD, c3:DWORD local r1:DWORD, r2:DWORD, r3:DWORD local topic:DWORD mov eax, fortuneDrawCards3D[0] xor edx, edx mov ecx, 22 div ecx mov c1, edx cmp fortuneDrawCards3D[0], 22 setae al movzx eax, al mov r1, eax ; 1 if reversed, 0 if upright mov eax, fortuneDrawCards3D[4] xor edx, edx mov ecx, 22 div ecx mov c2, edx cmp fortuneDrawCards3D[4], 22 setae al movzx eax, al mov r2, eax mov eax, fortuneDrawCards3D[8] xor edx, edx mov ecx, 22 div ecx mov c3, edx cmp fortuneDrawCards3D[8], 22 setae al movzx eax, al mov r3, eax invoke DetectTopic3D, OFFSET fortuneQuestion3D mov topic, eax ; Reset answer buffer mov fortuneAnswer3D[0], 0 ; Header invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strReadingHeading ; Card 1: Situation invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strReadingSit mov eax, c1 mov eax, cardNamesTable[eax*4] invoke FortuneStrCat, OFFSET fortuneAnswer3D, eax invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strSpace cmp r1, 0 je @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strCardReversed jmp fortune_c1_interp @@: invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strCardUpright fortune_c1_interp: invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strDashSpace mov eax, c1 cmp r1, 0 je @F mov eax, cardSitRTable[eax*4] jmp fortune_c1_add @@: mov eax, cardSitUTable[eax*4] fortune_c1_add: invoke FortuneStrCat, OFFSET fortuneAnswer3D, eax invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strNewLine ; Card 2: Obstacle invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strReadingObs mov eax, c2 mov eax, cardNamesTable[eax*4] invoke FortuneStrCat, OFFSET fortuneAnswer3D, eax invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strSpace cmp r2, 0 je @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strCardReversed jmp fortune_c2_interp @@: invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strCardUpright fortune_c2_interp: invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strDashSpace mov eax, c2 cmp r2, 0 je @F mov eax, cardObsRTable[eax*4] jmp fortune_c2_add @@: mov eax, cardObsUTable[eax*4] fortune_c2_add: invoke FortuneStrCat, OFFSET fortuneAnswer3D, eax invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strNewLine ; Card 3: Outcome invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strReadingOut mov eax, c3 mov eax, cardNamesTable[eax*4] invoke FortuneStrCat, OFFSET fortuneAnswer3D, eax invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strSpace cmp r3, 0 je @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strCardReversed jmp fortune_c3_interp @@: invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strCardUpright fortune_c3_interp: invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strDashSpace mov eax, c3 cmp r3, 0 je @F mov eax, cardOutRTable[eax*4] jmp fortune_c3_add @@: mov eax, cardOutUTable[eax*4] fortune_c3_add: invoke FortuneStrCat, OFFSET fortuneAnswer3D, eax invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strNewLine ; Synthesis & Topic invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strReadingSynth cmp topic, 1 jne @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strTopicCasino @@: cmp topic, 2 jne @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strTopicLove @@: cmp topic, 3 jne @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strTopicStudy @@: cmp topic, 4 jne @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strTopicFuture @@: ret GenerateTarotReadingMind3D ENDP ; GenerateStudentGradeMind3D: Evaluates borderline student grade GenerateStudentGradeMind3D PROC uses ebx esi edi local c1:DWORD, c2:DWORD, c3:DWORD local r1:DWORD, r2:DWORD, r3:DWORD local karma:DWORD local pickHigh:DWORD mov eax, fortuneDrawCards3D[0] xor edx, edx mov ecx, 22 div ecx mov c1, edx cmp fortuneDrawCards3D[0], 22 setae al movzx eax, al mov r1, eax mov eax, fortuneDrawCards3D[4] xor edx, edx mov ecx, 22 div ecx mov c2, edx cmp fortuneDrawCards3D[4], 22 setae al movzx eax, al mov r2, eax mov eax, fortuneDrawCards3D[8] xor edx, edx mov ecx, 22 div ecx mov c3, edx cmp fortuneDrawCards3D[8], 22 setae al movzx eax, al mov r3, eax ; Calculate karma points from cards + name letters xor ebx, ebx ; Card 1: upright = +2, rev = -1 cmp r1, 0 jne @F add ebx, 2 jmp fortune_karma_c2 @@: dec ebx fortune_karma_c2: ; Card 2: obstacle reversed = inner struggle (-2), upright = challenge (+1) cmp r2, 0 jne @F inc ebx jmp fortune_karma_c3 @@: sub ebx, 2 fortune_karma_c3: ; Card 3: final outcome card karma influence mov eax, c3 mov eax, cardKarmaTable[eax*4] cmp r3, 0 je @F neg eax @@: add ebx, eax ; Name letters influence (hash sum) xor ecx, ecx lea esi, studentName3D fortune_name_hash: lodsb test al, al jz fortune_name_hash_done movzx eax, al add ecx, eax jmp fortune_name_hash fortune_name_hash_done: test ecx, 1 jz @F inc ebx ; Odd letter hash gives +1 karma boost @@: mov karma, ebx mov studentKarmaSum3D, ebx ; Determine if high or low grade wins ; If karma >= 1 -> higher grade, else lower grade cmp ebx, 1 jge fortune_pick_high mov pickHigh, 0 jmp fortune_format_student fortune_pick_high: mov pickHigh, 1 fortune_format_student: mov fortuneAnswer3D[0], 0 invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strHeadingStudent invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strLabelStudent invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET studentName3D invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strLabelBorn invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET studentYear3D invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strLabelBornEnd mov eax, studentChoice3D cmp eax, 5 jb @F xor eax, eax @@: mov eax, gradeChoicesTable[eax*4] invoke FortuneStrCat, OFFSET fortuneAnswer3D, eax invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strNewLine ; Card 1: Study Habits invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strCard1Prefix mov eax, c1 mov eax, cardNamesTable[eax*4] invoke FortuneStrCat, OFFSET fortuneAnswer3D, eax invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strSpace cmp r1, 0 je @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strCardReversed invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strDashSpace mov eax, c1 mov eax, cardStudNTable[eax*4] invoke FortuneStrCat, OFFSET fortuneAnswer3D, eax jmp fortune_stud_c2 @@: invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strCardUpright invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strDashSpace mov eax, c1 mov eax, cardStudPTable[eax*4] invoke FortuneStrCat, OFFSET fortuneAnswer3D, eax fortune_stud_c2: invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strNewLine invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strCard2Prefix mov eax, c2 mov eax, cardNamesTable[eax*4] invoke FortuneStrCat, OFFSET fortuneAnswer3D, eax invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strSpace cmp r2, 0 je @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strCardReversed invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strDashSpace mov eax, c2 mov eax, cardStudNTable[eax*4] invoke FortuneStrCat, OFFSET fortuneAnswer3D, eax jmp fortune_stud_c3 @@: invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strCardUpright invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strDashSpace mov eax, c2 mov eax, cardStudPTable[eax*4] invoke FortuneStrCat, OFFSET fortuneAnswer3D, eax fortune_stud_c3: invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strNewLine invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strCard3Prefix mov eax, c3 mov eax, cardNamesTable[eax*4] invoke FortuneStrCat, OFFSET fortuneAnswer3D, eax invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strSpace cmp r3, 0 je @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strCardReversed invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strDashSpace mov eax, c3 mov eax, cardOutRTable[eax*4] invoke FortuneStrCat, OFFSET fortuneAnswer3D, eax jmp fortune_stud_verdict @@: invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strCardUpright invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strDashSpace mov eax, c3 mov eax, cardOutUTable[eax*4] invoke FortuneStrCat, OFFSET fortuneAnswer3D, eax fortune_stud_verdict: cmp pickHigh, 1 jne fortune_verdict_low ; High Verdict (e.g. 10 or 9 or 8 or 5 or 6) invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strVerdictHighPrefix mov eax, studentChoice3D cmp eax, 0 jne @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strScore10 jmp fortune_verdict_high_done @@: cmp eax, 1 jne @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strScore9 jmp fortune_verdict_high_done @@: cmp eax, 2 jne @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strScore8 jmp fortune_verdict_high_done @@: cmp eax, 3 jne @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strScore5 jmp fortune_verdict_high_done @@: invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strScore6 fortune_verdict_high_done: invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strVerdictSuffix invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strAdviceHigh jmp fortune_stud_end fortune_verdict_low: ; Low Verdict (e.g. 9 or 8 or 7 or 4 or 5) invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strVerdictLowPrefix mov eax, studentChoice3D cmp eax, 0 jne @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strScore9 jmp fortune_verdict_low_done @@: cmp eax, 1 jne @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strScore8 jmp fortune_verdict_low_done @@: cmp eax, 2 jne @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strScore7 jmp fortune_verdict_low_done @@: cmp eax, 3 jne @F invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strScore4 jmp fortune_verdict_low_done @@: invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strScore5 fortune_verdict_low_done: invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strVerdictSuffix invoke FortuneStrCat, OFFSET fortuneAnswer3D, OFFSET strAdviceLow fortune_stud_end: ret GenerateStudentGradeMind3D ENDP