- Offline neural worker based on llama.cpp (fortune-engine.exe) with local Qwen3-4B model support - Native assembly Tarot 3-card spread divination and teacher grade divination mode - Text input dialog in MODE_FORTUNE communicating over anonymous pipes - Clean process lifecycle management, WM_CHAR dispatch and fallback handling - Test suites and packaging tools for offline release
1033 lines
55 KiB
Python
1033 lines
55 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""
|
||
Generator for Fortune Mind system (CP1251):
|
||
- src_graphics/fortune_mind_data.inc
|
||
- src_graphics/fortune_mind.inc
|
||
|
||
Generates the complete native algorithmic Tarot Mind and Teacher Grade Divination system.
|
||
"""
|
||
from pathlib import Path
|
||
|
||
ROOT = Path(__file__).resolve().parents[2]
|
||
|
||
CARDS = [
|
||
("Шут", "0",
|
||
"Начало нового пути, чистый лист, смелый шаг в неизвестность.",
|
||
"Безрассудство, легкомыслие, риск без подготовки и плана.",
|
||
"Неожиданный поворот судьбы или наивный подход к делу.",
|
||
"Страх сделать первый шаг, нежелание учиться на ошибках.",
|
||
"Доверься интуиции и начни с чистого сердца; дерзай.",
|
||
"Не торопись прыгать в омут с головой; взвесь последствия.",
|
||
"Студент полон энтузиазма, легко схватывает новые идеи на лету.",
|
||
"Сдавал лабы наугад, надеясь на великую удачу и чудо в 23:59.",
|
||
1),
|
||
("Маг", "I",
|
||
"Полный контроль над ресурсами, мастерство, воля и лидерство.",
|
||
"Манипуляции, распыление сил, неиспользованный потенциал.",
|
||
"Необходимость проявить решительность и взять инициативу.",
|
||
"Сомнения в собственных силах или пустая трата энергии.",
|
||
"У тебя есть все инструменты для триумфа; действуй смело.",
|
||
"Сконцентрируйся на главном, не пытайся объять необъятное.",
|
||
"Самостоятельно писал код, задавал умные вопросы преподавателю.",
|
||
"Пытался заговорить зубы на коллоквиуме и переложить вину на баг.",
|
||
1),
|
||
("Верховная Жрица", "II",
|
||
"Глубокая интуиция, тайные знания, мудрое наблюдение.",
|
||
"Скрытые мотивы, игнорирование знаков, тайное станет явным.",
|
||
"Не все карты раскрыты; ситуация требует терпеливого изучения.",
|
||
"Заблуждения и поверхностные суждения мешают увидеть суть.",
|
||
"Прислушайся к внутреннему голосу; тайное скоро прояснится.",
|
||
"Не доверяй слухам; перепроверяй факты и сохраняй ясность.",
|
||
"Тихий студент, но на зачёте раскрыл глубину понимания предмета.",
|
||
"Молчал на парах как партизан, скрывая отсутствие конспекта.",
|
||
1),
|
||
("Императрица", "III",
|
||
"Плодородие, расцвет, гармония, забота и рост результатов.",
|
||
"Творческий застой, пресыщение, излишняя опека или лень.",
|
||
"Почва готова для прекрасных всходов; время развивать дело.",
|
||
"Лень и праздность тормозят воплощение задуманного.",
|
||
"Всё задуманное принесет обильные плоды; доверься созиданию.",
|
||
"Удели внимание практическим деталям, не витай в облаках.",
|
||
"Конспекты написаны аккуратно, лабораторные оформлены образцово.",
|
||
"Слишком расслабился в середине семестра, уповая на автомат.",
|
||
1),
|
||
("Император", "IV",
|
||
"Твёрдый порядок, авторитет, железная дисциплина и стабильность.",
|
||
"Тирания, упрямство, закостенелость или потеря контроля.",
|
||
"Требуется навести строгий порядок и выстроить четкие границы.",
|
||
"Хаос в делах и нехватка самодисциплины создают заторы.",
|
||
"Держи ситуацию под контролем; твой авторитет непоколебим.",
|
||
"Будь гибче: излишнее упрямство может разрушить договоренности.",
|
||
"Дисциплинированный студент, ни одного пропуска без справки.",
|
||
"Спорил с методичкой и пытался доказать, что преподаватель неправ.",
|
||
1),
|
||
("Иерофант", "V",
|
||
"Мудрость традиций, наставничество, духовность и верность слову.",
|
||
"Догматизм, лицемерие, следование устаревшим догмам.",
|
||
"Ситуация требует уважения к правилам и совету наставника.",
|
||
"Нежелание признавать чужой авторитет и полезный опыт.",
|
||
"Следуй проверенным традициям и заветам старших учителей.",
|
||
"Думай своей головой, не слепо верь всему, что проповедуют.",
|
||
"Почитает авторитет кафедры, внимательно слушал каждую лекцию.",
|
||
"Списывал по старым лекциям пятилетней давности, которые устарели.",
|
||
1),
|
||
("Влюблённые", "VI",
|
||
"Гармоничный выбор, зов сердца, доверие и союз двух начал.",
|
||
"Внутренний раскол, нерешительность, конфликт интересов.",
|
||
"Перед тобой судьбоносный перекресток; слушай свое сердце.",
|
||
"Колебания между долгом и сиюминутным искушением.",
|
||
"Искренний выбор приведет к гармонии и взаимному счастью.",
|
||
"Не откладывай решение; неопределенность вытягивает силы.",
|
||
"Искренне любит предмет, учился по призванию и велению души.",
|
||
"Выбирал между сном, личной жизнью и домашкой — и домашка проиграла.",
|
||
0),
|
||
("Колесница", "VII",
|
||
"Стремительный прорыв, победа над обстоятельствами, триумф.",
|
||
"Потеря управления, срыв планов, агрессивный напор.",
|
||
"Энергия бьет ключом; время набрать максимальную скорость.",
|
||
"Спешка и внутренние противоречия грозят сбить с колеи.",
|
||
"Ты добьешься триумфа благодаря воле и концентрации.",
|
||
"Притормози на поворотах; не пытайся пробить стену лбом.",
|
||
"Сдал все долги за рекордные три дня на бешеной скорости.",
|
||
"Летел по предмету без тормозов, наделав кучу глупых ошибок.",
|
||
1),
|
||
("Сила", "VIII",
|
||
"Внутреннее благородство, укрощение страстей, стойкость духа.",
|
||
"Сомнения в себе, слабость перед искушением, упадок сил.",
|
||
"Мягкая настойчивость одолеет любые внешние препятствия.",
|
||
"Страх неудачи парализует; не хватает веры в свои силы.",
|
||
"Ты сильнее любых бурь; победитель выйдет с улыбкой.",
|
||
"Не дави силой; прояви дипломатию, терпение и великодушие.",
|
||
"Стойко выдержал все каверзные вопросы на коллоквиуме.",
|
||
"Пасовал перед сложными задачами и опускал руки раньше времени.",
|
||
1),
|
||
("Отшельник", "IX",
|
||
"Поиск истины, глубинная концентрация, мудрое уединение.",
|
||
"Замкнутость, одиночество, упрямый отказ от помощи мира.",
|
||
"Время поставить дела на паузу и разобраться в себе.",
|
||
"Чрезмерная изоляция мешает получить поддержку коллег.",
|
||
"Свет твоего разума укажет верную тропу сквозь тьму.",
|
||
"Выйди в мир: ответы лежат во взаимодействии с людьми.",
|
||
"Самостоятельно изучил сложнейшие разделы курса в тишине ночи.",
|
||
"Ушел в глубокий академический астрал, проигнорировав дедлайны.",
|
||
0),
|
||
("Колесо Фортуны", "X",
|
||
"Счастливый шанс, поворот колеса судьбы, кармический взлет.",
|
||
"Временный спад, сопротивление неизбежным переменам.",
|
||
"Судьба делает виток; грядут великие перемены.",
|
||
"Попытка держаться за прошлое, когда колесо уже повернулось.",
|
||
"Удача на твоей стороне; лови момент, пока фортуна улыбается.",
|
||
"Всё циклично: за полосой испытаний неизбежно придет рассвет.",
|
||
"Вытянул именно тот единственный счастливый билет, который учил.",
|
||
"Надеялся исключительно на слепую удачу, не открыв учебник.",
|
||
1),
|
||
("Справедливость", "XI",
|
||
"Закон кармы, абсолютная честность, объективный вердикт.",
|
||
"Предвзятость, несправедливый упрек, уклонение от ответа.",
|
||
"Время подвести честный итог и взвесить все 'за' и 'против'.",
|
||
"Попытка обойти правила обернется строгим уроком судьбы.",
|
||
"Справедливость восторжествует; каждый получит по заслугам.",
|
||
"Будь честен перед собой: признай ошибки и исправь их.",
|
||
"Работал стабильно, честно заслужил каждую крупицу своих баллов.",
|
||
"Пытался списать со смартфона прямо перед глазами комиссии.",
|
||
1),
|
||
("Повешенный", "XII",
|
||
"Новый взгляд на вещи, добровольная жертва ради высшей цели.",
|
||
"Бесполезное упрямство, застревание, позиция жертвы.",
|
||
"Ситуация требует взглянуть на всё под совершенно иным углом.",
|
||
"Застой и нежелание пожертвовать малым ради победы.",
|
||
"Пауза пойдет на пользу; озарение придет в момент покоя.",
|
||
"Хватит тянуть резину; начни действовать прямо сейчас.",
|
||
"Необычный подход к решению задач, оригинальное мышление.",
|
||
"Завис в долгах до самой сессии, придумывая нелепые оправдания.",
|
||
0),
|
||
("Смерть", "XIII",
|
||
"Глубинная трансформация, завершение старого цикла, перерождение.",
|
||
"Цепляние за отжившее, страх перемен, затянувшаяся агония.",
|
||
"Старый этап подошел к финалу; расчисти место новому рассвету.",
|
||
"Нежелание отпустить то, что уже исчерпало себя.",
|
||
"Сбрось старую оболочку; впереди ждет обновленная судьба.",
|
||
"Не бойся закрыть старую главу; перемены несут благо.",
|
||
"Полностью переписал проект с нуля за ночь и блестяще защитил.",
|
||
"До последнего защищал неработающий багованный код из сети.",
|
||
0),
|
||
("Умеренность", "XIV",
|
||
"Золотая середина, баланс, гармония противоположностей.",
|
||
"Дисбаланс, крайности, поспешность и чрезмерный аппетит.",
|
||
"Сохраняй внутреннее равновесие и спокойный шаг.",
|
||
"Нетерпение и эмоциональные качели расшатывают лодку.",
|
||
"Тише едешь — дальше будешь; время работает на тебя.",
|
||
"Избегай крайностей: чрезмерный азарт приведет к потерям.",
|
||
"Равномерно распределял нагрузку в течение всего учебного года.",
|
||
"Всю ночь зубрил, пришел на экзамен с тремором и чашкой кофе.",
|
||
1),
|
||
("Дьявол", "XV",
|
||
"Магнетизм, земные искушения, материальная хватка, азарт.",
|
||
"Освобождение от иллюзий, падение оков, разоблачение страстей.",
|
||
"Сильное искушение или зависимость от сиюминутных страстей.",
|
||
"Оковы вредных привычек и самообман держат в плену.",
|
||
"Осознай свои истинные мотивы; не продавай душу за мелочи.",
|
||
"Сбрось оковы сомнений: никто не властен над твоей волей.",
|
||
"Хитрый, пробивной ум, найдет выход из любой безнадеги.",
|
||
"Использовал нейросеть для генерации диплома, даже не читая текст.",
|
||
-1),
|
||
("Башня", "XVI",
|
||
"Крах иллюзий, очистительная буря, внезапное освобождение.",
|
||
"Катастрофа, упорное отрицание фактов, попытка склеить руины.",
|
||
"Ненадежные основания рушатся, чтобы ты построил твердыню.",
|
||
"Внезапный удар судьбы застигнет врасплох, если медлить.",
|
||
"Прими бурю как очищение: на обломках вырастет величие.",
|
||
"Не пытайся спасти карточный домик; строй заново на скале.",
|
||
"После жесткого разноса на зачете собрался и всё пересдал.",
|
||
"Уронил продакшн, удалил репозиторий перед самой сдачей проекта.",
|
||
-1),
|
||
("Звезда", "XVII",
|
||
"Светлая надежда, вдохновение, путеводная звезда и благодать.",
|
||
"Разочарование, пессимизм, утрата веры в счастливое завтра.",
|
||
"Перед тобой ясный ориентир; верь в свою путеводную мечту.",
|
||
"Сомнения в завтрашнем дне туманят истинный свет.",
|
||
"Твоя звезда ведет тебя к триумфу; не сворачивай с тропы.",
|
||
"Не витай в мечтах без дела: воплощай надежду в поступках.",
|
||
"Светлая голова, вдохновлял всю группу своими ответами.",
|
||
"Мечтал о красном дипломе, лежа на диване с чипсами.",
|
||
1),
|
||
("Луна", "XVIII",
|
||
"Тайны подсознания, интуиция, путешествие сквозь сумрак.",
|
||
"Иллюзии, страхи, обман, самообман и блуждание в потемках.",
|
||
"Ситуация окутана туманом; берегись скрытых ловушек.",
|
||
"Страхи и тревоги рисуют мнимые угрозы на пустом месте.",
|
||
"Включи фонарь разума; не верь теням, ищи проверенные факты.",
|
||
"Пройди сквозь сумрак не дрогнув; утро рассеет морок.",
|
||
"Нестандартно мыслит, умеет находить обходные элегантные пути.",
|
||
"Блуждал в трех соснах, запутавшись в простейших формулах.",
|
||
0),
|
||
("Солнце", "XIX",
|
||
"Ясный триумф, истина, радость, благословение и успех.",
|
||
"Эгоизм, временные облака на горизонте, ослепление гордыней.",
|
||
"Всё прозрачно и ясно; судьба озарена лучами славы.",
|
||
"Чрезмерная самоуверенность может ослепить перед финишем.",
|
||
"Тебя ждет безоговорочная победа и признание заслуг.",
|
||
"Поделись радостью с окружающими; гордыня губит триумф.",
|
||
"Звезда курса, безупречные знания, гордость преподавателя.",
|
||
"Слишком задирал нос перед одногруппниками, схлопотал допвопрос.",
|
||
1),
|
||
("Суд", "XX",
|
||
"Пробуждение, духовный подъем, избавление от прошлых долгов.",
|
||
"Сомнения, страх перед воздаянием, упущенный второй шанс.",
|
||
"Зов трубы возвещает час истины: пора расправить крылья.",
|
||
"Груз старых ошибок тянет вниз; пора рассчитаться со спорами.",
|
||
"Час воздаяния настал: ты готов перейти на высший уровень.",
|
||
"Не бойся суда: твоя совесть чиста, если ты действовал честно.",
|
||
"Смог блестяще реабилитироваться на комиссии и доказать знания.",
|
||
"До последнего надеялся, что ведомость закроют без его участия.",
|
||
1),
|
||
("Мир", "XXI",
|
||
"Абсолютный триумф, совершенство, гармоничное завершение пути.",
|
||
"Недоделанные штрихи, страх перед новым горизонтом.",
|
||
"Все пазлы сложились в шедевр; ты на вершине успеха.",
|
||
"Остался всего один шаг до финала; не бросай дело у цели.",
|
||
"Цель достигнута, впереди открываются врата нового мира.",
|
||
"Заверши начатое до конца; не оставляй хвостов за спиной.",
|
||
"Идеальный студент, курс освоен на все 100%, эталонная работа.",
|
||
"Не хватило ровно одной подписи в обходном листе для полного триумфа.",
|
||
1)
|
||
]
|
||
|
||
TOPICS = [
|
||
("казино_деньги", ["покер", "деньг", "банк", "казино", "ставк", "выигр", "куш", "фишк", "рулетк", "джекпот", "богат", "золот", "выигра"]),
|
||
("любовь", ["любов", "девушк", "парен", "чувств", "отношен", "брак", "сердц", "любит", "пара", "женщин", "мужчин"]),
|
||
("учеба", ["учеб", "экзамен", "сесси", "зачет", "препод", "универ", "балл", "оценк", "институт", "диплом", "лаб", "семестр"]),
|
||
("судьба", ["будущ", "судьб", "выбор", "что ждет", "стоит ли", "как поступить", "жизн", "завтра", "путь", "дорог"])
|
||
]
|
||
|
||
|
||
def generate():
|
||
# 1. Generate fortune_mind_data.inc
|
||
d_lines = [
|
||
'; ==============================================================================',
|
||
'; FORTUNE MIND DATA - MASM32 / CP1251',
|
||
'; Algorithmic Tarot Oracle & Teacher Grade Divination Database',
|
||
'; ==============================================================================',
|
||
'',
|
||
'FORTUNE_SUBMODE_MENU equ 0',
|
||
'FORTUNE_SUBMODE_TAROT equ 1',
|
||
'FORTUNE_SUBMODE_STUDENT equ 2',
|
||
'',
|
||
'.data',
|
||
'ALIGN 4',
|
||
'fortuneSubMode3D dd 0',
|
||
'fortuneCardsDrawn3D dd 0',
|
||
'fortuneDrawCards3D dd 0,0,0',
|
||
'',
|
||
'studentName3D db 64 dup(0)',
|
||
'studentNameLen3D dd 0',
|
||
'studentYear3D db 16 dup(0)',
|
||
'studentYearLen3D dd 0',
|
||
'studentChoice3D dd 0 ; 0=9-10, 1=8-9, 2=7-8, 3=4-5, 4=5-6',
|
||
'studentField3D dd 0 ; 0=Name, 1=Year, 2=Choice',
|
||
'studentDone3D dd 0',
|
||
'studentKarmaSum3D dd 0',
|
||
'',
|
||
'; UI Static Strings (CP1251)',
|
||
'fortuneMenuTitle3D db "ТАИНСТВЕННЫЙ ОРАКУЛ КАЗИНО",0',
|
||
'fortuneMenuGreeting1_3D db "«Приветствую тебя, путник. Карты видят то, что скрыто от глаз.",0',
|
||
'fortuneMenuGreeting2_3D db "С чем ты предстал перед священным оракулом?»",0',
|
||
'fortuneMenuOpt1_3D db "[1] Обычное гадание на картах Таро (вопрос судьбе)",0',
|
||
'fortuneMenuOpt2_3D db "[2] Кабинет преподавателя: решить спорную оценку студента",0',
|
||
'fortuneMenuOpt0_3D db "[0] Покинуть обитель гадалки",0',
|
||
'',
|
||
'strTarotRole1 db "1. СИТУАЦИЯ",0',
|
||
'strTarotRole2 db "2. ПРЕПЯТСТВИЕ",0',
|
||
'strTarotRole3 db "3. ИСХОД",0',
|
||
'',
|
||
'strStudRole1 db "1. КАРМА УЧЕБЫ",0',
|
||
'strStudRole2 db "2. ТАЙНЫЙ ГРЕХ",0',
|
||
'strStudRole3 db "3. СУД ВСЕЛЕННОЙ",0',
|
||
'',
|
||
'strCardUpright db "[ПРЯМАЯ]",0',
|
||
'strCardReversed db "[ПЕРЕВЕРНУТА]",0',
|
||
'',
|
||
'strAskPrompt db "Задай вопрос картам (Enter - спросить):",0',
|
||
'strStudentTitle db "КАБИНЕТ ПРЕПОДАВАТЕЛЯ: СУДЬБА СТУДЕНТА",0',
|
||
'strStudentPromptName db "ФИО студента : ",0',
|
||
'strStudentPromptYear db "Год рождения : ",0',
|
||
'strStudentPromptChoice db "Спорный балл : [1] 9-10 [2] 8-9 [3] 7-8 [4] 4-5 [5] 5-6",0',
|
||
'strStudentAction db "Enter / Клик: Рассудить студента | Tab: Сменить поле | Esc: Меню",0',
|
||
'strBtnNextStudent db "[СЛЕДУЮЩИЙ СТУДЕНТ]",0',
|
||
'strBtnMenu db "[В МЕНЮ]",0',
|
||
'strBtnAsk db "[СПРОСИТЬ]",0',
|
||
'strBtnExit db "[ВЫЙТИ]",0',
|
||
'strDefaultStudentName db "Иванов Иван",0',
|
||
'strDefaultStudentYear db "2005",0',
|
||
'',
|
||
'; Grade Choice Display Names',
|
||
'strGradeChoice0 db "9 или 10",0',
|
||
'strGradeChoice1 db "8 или 9",0',
|
||
'strGradeChoice2 db "7 или 8",0',
|
||
'strGradeChoice3 db "4 или 5",0',
|
||
'strGradeChoice4 db "5 или 6",0',
|
||
'',
|
||
'gradeChoicesTable dd OFFSET strGradeChoice0, OFFSET strGradeChoice1, OFFSET strGradeChoice2, OFFSET strGradeChoice3, OFFSET strGradeChoice4',
|
||
'',
|
||
'; Card Data Structures',
|
||
]
|
||
|
||
for i, c in enumerate(CARDS):
|
||
name, rom, sit_u, sit_r, obs_u, obs_r, out_u, out_r, st_p, st_n, k = c
|
||
d_lines.append(f'cardName_{i} db "{rom} {name}",0')
|
||
d_lines.append(f'cardSitU_{i} db "{sit_u}",0')
|
||
d_lines.append(f'cardSitR_{i} db "{sit_r}",0')
|
||
d_lines.append(f'cardObsU_{i} db "{obs_u}",0')
|
||
d_lines.append(f'cardObsR_{i} db "{obs_r}",0')
|
||
d_lines.append(f'cardOutU_{i} db "{out_u}",0')
|
||
d_lines.append(f'cardOutR_{i} db "{out_r}",0')
|
||
d_lines.append(f'cardStudP_{i} db "{st_p}",0')
|
||
d_lines.append(f'cardStudN_{i} db "{st_n}",0')
|
||
|
||
d_lines.append('')
|
||
d_lines.append('ALIGN 4')
|
||
d_lines.append('cardNamesTable dd ' + ', '.join(f'OFFSET cardName_{i}' for i in range(len(CARDS))))
|
||
d_lines.append('cardSitUTable dd ' + ', '.join(f'OFFSET cardSitU_{i}' for i in range(len(CARDS))))
|
||
d_lines.append('cardSitRTable dd ' + ', '.join(f'OFFSET cardSitR_{i}' for i in range(len(CARDS))))
|
||
d_lines.append('cardObsUTable dd ' + ', '.join(f'OFFSET cardObsU_{i}' for i in range(len(CARDS))))
|
||
d_lines.append('cardObsRTable dd ' + ', '.join(f'OFFSET cardObsR_{i}' for i in range(len(CARDS))))
|
||
d_lines.append('cardOutUTable dd ' + ', '.join(f'OFFSET cardOutU_{i}' for i in range(len(CARDS))))
|
||
d_lines.append('cardOutRTable dd ' + ', '.join(f'OFFSET cardOutR_{i}' for i in range(len(CARDS))))
|
||
d_lines.append('cardStudPTable dd ' + ', '.join(f'OFFSET cardStudP_{i}' for i in range(len(CARDS))))
|
||
d_lines.append('cardStudNTable dd ' + ', '.join(f'OFFSET cardStudN_{i}' for i in range(len(CARDS))))
|
||
d_lines.append('cardKarmaTable dd ' + ', '.join(str(c[10]) for c in CARDS))
|
||
d_lines.append('')
|
||
|
||
# Helper strings for synthesis
|
||
d_lines.append('strHeadingStudent db "=== СУДЕБНЫЙ РАСКЛАД ТАРО: СТУДЕНТ ===",10,0')
|
||
d_lines.append('strLabelStudent db "Студент: ",0')
|
||
d_lines.append('strLabelBorn db " (",0')
|
||
d_lines.append('strLabelBornEnd db " г.р.) | Спорная отметка: ",0')
|
||
d_lines.append('strCard1Prefix db "1. Карма учебы: ",0')
|
||
d_lines.append('strCard2Prefix db "2. Тайный грех: ",0')
|
||
d_lines.append('strCard3Prefix db "3. Суд Вселенной: ",0')
|
||
d_lines.append('strVerdictHighPrefix db 10,"*** ВЕРДИКТ СУДЬБЫ: СТАВИТЬ БОЛЬШИЙ БАЛЛ (",0')
|
||
d_lines.append('strVerdictLowPrefix db 10,"*** ВЕРДИКТ СУДЬБЫ: СТАВИТЬ МЕНЬШИЙ БАЛЛ (",0')
|
||
d_lines.append('strVerdictSuffix db ")! ***",10,0')
|
||
d_lines.append('strAdviceHigh db "Совет преподавателю: Студент полностью искупил ночные грехи и проявил искру таланта. Поставьте высший балл — это окрылит его!",0')
|
||
d_lines.append('strAdviceLow db "Совет преподавателю: Карты суровы, но справедливы. Меньший балл станет целебным уроком и научит не сдавать лабы за 5 минут до дедлайна!",0')
|
||
|
||
d_lines.append('strReadingHeading db "=== РАСКЛАД ТАРО ИЗ 3 КАРТ ===",10,0')
|
||
d_lines.append('strReadingSit db "1. Ситуация (Исток): ",0')
|
||
d_lines.append('strReadingObs db "2. Препятствие (Вызов): ",0')
|
||
d_lines.append('strReadingOut db "3. Исход (Совет): ",0')
|
||
d_lines.append('strReadingSynth db 10,"Синтез оракула: Карты указали путь. Твоя воля определяет исход — действуй разумно и помни знаки судьбы.",0')
|
||
d_lines.append('strNewLine db 10,0')
|
||
d_lines.append('strSpace db " ",0')
|
||
d_lines.append('strDashSpace db " — ",0')
|
||
d_lines.append('strColonSpace db ": ",0')
|
||
d_lines.append('strTopicCasino db 10,"(Оракул чувствует дыхание казино и азарта: Фортуна любит смелых, но карает жадных!)",0')
|
||
d_lines.append('strTopicLove db 10,"(Оракул слышит биение твоего сердца: в любви важны искренность и доверие, а не гордыня.)",0')
|
||
d_lines.append('strTopicStudy db 10,"(Оракул видит свитки знаний и дедлайны: упорство и труд сломят гранит науки!)",0')
|
||
d_lines.append('strTopicFuture db 10,"(Оракул вглядывается в туман грядущего: будущее не высечено в камне, ты кузнец своего пути!)",0')
|
||
d_lines.append('')
|
||
# Keyword strings for topic detection
|
||
d_lines.append('kwPoker db "покер",0')
|
||
d_lines.append('kwMoney db "деньг",0')
|
||
d_lines.append('kwBank db "банк",0')
|
||
d_lines.append('kwBet db "ставк",0')
|
||
d_lines.append('kwCasino db "казино",0')
|
||
d_lines.append('kwWin db "выигр",0')
|
||
d_lines.append('kwRoulette db "рулетк",0')
|
||
d_lines.append('kwLove db "любов",0')
|
||
d_lines.append('kwGirl db "девушк",0')
|
||
d_lines.append('kwBoy db "парен",0')
|
||
d_lines.append('kwRel db "отношен",0')
|
||
d_lines.append('kwStudy db "учеб",0')
|
||
d_lines.append('kwExam db "экзамен",0')
|
||
d_lines.append('kwSession db "сесси",0')
|
||
d_lines.append('kwScore db "балл",0')
|
||
d_lines.append('kwGrade db "оценк",0')
|
||
d_lines.append('kwFuture db "будущ",0')
|
||
d_lines.append('kwFate db "судьб",0')
|
||
d_lines.append('kwChoice db "выбор",0')
|
||
d_lines.append('')
|
||
d_lines.append('strScore10 db "10",0')
|
||
d_lines.append('strScore9 db "9",0')
|
||
d_lines.append('strScore8 db "8",0')
|
||
d_lines.append('strScore7 db "7",0')
|
||
d_lines.append('strScore6 db "6",0')
|
||
d_lines.append('strScore5 db "5",0')
|
||
d_lines.append('strScore4 db "4",0')
|
||
d_lines.append('')
|
||
d_lines.append('SubStrI3D PROTO :DWORD,:DWORD')
|
||
d_lines.append('')
|
||
|
||
data_content = '\n'.join(d_lines) + '\n'
|
||
|
||
# 2. Generate fortune_mind.inc
|
||
c_lines = [
|
||
'; ==============================================================================',
|
||
'; 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',
|
||
''
|
||
]
|
||
|
||
code_content = '\n'.join(c_lines) + '\n'
|
||
|
||
# Save files in CP1251
|
||
data_path = ROOT / 'src_graphics/fortune_mind_data.inc'
|
||
code_path = ROOT / 'src_graphics/fortune_mind.inc'
|
||
|
||
data_path.write_bytes(data_content.encode('cp1251'))
|
||
print(f'[OK] Wrote {data_path} ({len(data_content)} chars, CP1251)')
|
||
|
||
code_path.write_bytes(code_content.encode('cp1251'))
|
||
print(f'[OK] Wrote {code_path} ({len(code_content)} chars, CP1251)')
|
||
|
||
|
||
if __name__ == '__main__':
|
||
generate()
|