// SPDX-License-Identifier: MIT // Copyright (c) 2026 Incoprea // Four-pair memory board // Not compiled or tested in-world // Setup: Owner-touch. Enter card numbers 1–8. Remember revealed symbols while matching four pairs. // Stop / restore: Stop responding and the listener closes after 90 seconds, or remove/disable the script. Owner-touch restarts the exercise. // Notes: Owner-only local exercise; no prizes, visitor records, network service, or persistent scores. Symbols are shown in private prompts and owner chat; no textures or inventory cards are required. // License: see LICENSE in this distribution. // Original Incoprea. MIT. Not compiled or tested in-world. integer channel; integer handle; close() { if(handle)llListenRemove(handle); handle=0; llSetTimerEvent(0.0); } ask(string prompt) { if(!handle) { channel=-1000-(integer)llFrand(1000000.0); handle=llListen(channel,"",llGetOwner(),""); } llTextBox(llGetOwner(),prompt,channel); llSetTimerEvent(90.0); } integer digit(string text,integer min,integer max) { if(llStringLength(text)!=1)return -1; integer n=llSubStringIndex("0123456789",text); if(nmax)return -1; return n; } list cards; list found; integer first=-1; integer pairs; string view() { string out=""; integer i; for(i=0;i<8;++i) { if(llListFindList(found,[i])>=0)out+=llList2String(cards,i); else out+=(string)(i+1); out+=" "; } return out; } start() { cards=llListRandomize(["A","A","B","B","C","C","D","D"],1); found=[]; pairs=0; first=-1; ask(view()+"\nChoose a card."); } answer(string s) { integer p=digit(s,1,8)-1; if(p<0||llListFindList(found,[p])>=0||p==first) { ask(view()+"\nChoose a different hidden card."); return; } string symbol=llList2String(cards,p); if(first<0) { first=p; ask("Card "+s+" is "+symbol+". Choose its partner."); return; } string old=llList2String(cards,first); string result="No match: "+old+" and "+symbol; if(old==symbol) { found+=[first,p]; ++pairs; result="Pair found: "+symbol; } first=-1; if(pairs==4) { close(); llOwnerSay("All four pairs found."); } else ask(result+"\n"+view()+"\nChoose another card."); } default { touch_start(integer count) { if(llDetectedKey(0)!=llGetOwner())return; close(); start(); } listen(integer ch,string name,key id,string message) { if(!handle||ch!=channel||id!=llGetOwner())return; answer(llStringTrim(message,STRING_TRIM)); } timer() { close(); llOwnerSay("Exercise paused. Touch to restart."); } changed(integer change) { if(change&CHANGED_OWNER)llResetScript(); } }