The following warnings occurred:
Warning [2] Use of undefined constant SAPI_NAME - assumed 'SAPI_NAME' (this will throw an Error in a future version of PHP) - Line: 3388 - File: inc/functions.php PHP 7.4.33-nmm7 (Linux)
File Line Function
/inc/functions.php 3388 errorHandler->error
/showthread.php 116 build_archive_link
Warning [2] Use of undefined constant IN_ARCHIVE - assumed 'IN_ARCHIVE' (this will throw an Error in a future version of PHP) - Line: 3331 - File: inc/functions.php PHP 7.4.33-nmm7 (Linux)
File Line Function
/inc/functions.php 3331 errorHandler->error
/inc/functions.php 3324 build_forum_breadcrumb
/showthread.php 195 build_forum_breadcrumb
Warning [2] Use of undefined constant IN_ARCHIVE - assumed 'IN_ARCHIVE' (this will throw an Error in a future version of PHP) - Line: 3331 - File: inc/functions.php PHP 7.4.33-nmm7 (Linux)
File Line Function
/inc/functions.php 3331 errorHandler->error
/showthread.php 195 build_forum_breadcrumb






Post Reply 
 
Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Swindler's Memory Game
Author Message
Mordaunt
Super Moderator
****

Posts: 1,237
Likes Given: 26
Likes Received: 55 in 43 posts
Joined: Mar 2012
Reputation: 35



Post: #1
Swindler's Memory Game
Found this while digging around my old server script pack.
Unaltered, seems to work fine still:

Code:
//[PLEVEL 1]
//memory

[FUNCTION memory]
// never give your players access strictly to the "memoryGame" function!  That could be VERY bad, allowing them to call functions by passing them as arguments (as in: [PLEVEL 1] memoryGame)
memoryGame memoryGame_playerWon, memoryGame_playerLost
//memoryGame 50,memoryGame_playerWon, memoryGame_playerLost
//memoryGame 99

// these functions are called ON THE GAME ITEM, so CONT is the player
// if you RETURN 1, the item will NOT be automatically deleted nor will the dialog be closed (both would otherwise occur after the function finishes) Maybe you can come up with some kind of purpose for this... or tweak things to your liking

// the function calls also make it easy for one of these to be assosciated with a physical game board, or a quest, etc.
[FUNCTION memoryGame_playerWon]
CONT.SYSMESSAGE @1153 You've won!

[FUNCTION memoryGame_playerLost]
CONT.SYSMESSAGE @1153 You've lost.

[COMMENT memoryGame]
Author: Swindler (Chris Galpin)
A find and replace of these would render this script more readable,
but would also take up more memory.  *shrugs*
I should probably just let it take more memory... but I haven't.
I guess I can deal with ambiguous property names at the moment.

MOREX: TAG.matches
MOREY: TAG.movesLeft
MOREZ: TAG.firstFlipped
MOREM: TAG.secondFlipped

Also, a good way to tweak the set of cards to your own liking is to comment out the if statement
that shows either the button or the gumppic to show just the gumppic, that way they're all face up
and you can see how various sets look, to minimize (or increase) player confusability to your own liking
since a lot of spell icons are really similar

[DEFNAME memoryGame]
memoryGame_backSide 01b91               // the gump id of the back of the cards
memoryGame_iconStart 01b7f              // there are 24 different cards, starting at this gump id
memoryGame_backSideSubstitute 01b7f     // if one of those 24 cards would be the same as backSide, use this instead for that card
memoryGame_maxFails 50                  // how many fails the player is allowed before they lose

[ITEMDEF i_memoryGame]
ID=i_memory
TYPE=t_eq_script
NAME=Memory Game

ON=@Create
       DISPID i_game_board     // this is really nice for people doing a .edit or .xedit, use it in your own scripts!

ON=@Timer
       IF <MOREX> == 24        // won
               IF !<ISEMPTY <TAG.onWinFunction>>
                       IF <<TAG.onWinFunction>> != 1   // it's necessary to repeat code here because combining this with the line above can result in a "Can't resolve <>" error because Sphere doesn't short-circuit operators
                               TRYSRC <CONT.UID> DIALOGCLOSE d_memoryGame -1
                               REMOVE  // I could remove the -1 above, and this REMOVE here, and it be handled on the ON 0 below, but I think the "call a button when closing via script" may be gone in newer versions of Sphere
                       ENDIF
               ELSE
                       TRYSRC <CONT.UID> DIALOGCLOSE d_memoryGame -1
                       REMOVE
               ENDIF
               RETURN 1
       ENDIF

       // this down here is for a mismatch
       MOREY -= 1      // decrement moves left
       IF !<MOREY>     // lost
               IF !<ISEMPTY <TAG.onLoseFunction>>
                       IF <<TAG.onLoseFunction>> != 1
                               TRYSRC <CONT.UID> DIALOGCLOSE d_memoryGame -1
                               REMOVE
                               RETURN 1
                       ENDIF
               ELSE
                       TRYSRC <CONT.UID> DIALOGCLOSE d_memoryGame -1   // this is as above
                       REMOVE
                       RETURN 1
               ENDIF
       ENDIF

       TRY TAG.card<MOREM> <TAG.card<MOREM>> & ~020    // unflip       &= might be implemented in some version...
       TRY TAG.card<MOREZ> <TAG.card<MOREZ>> & ~020    // unflip
       MOREZ                   // set no card flipped (first card.. don't need to unset second card morem)

       TRYSRC <CONT.UID> DIALOG d_memoryGame
       RETURN 1

[FUNCTION memoryGame]
NEW <FINDID.i_memoryGame>
IF <NEW.UID>
       NEW.DIALOG d_memoryGame // lookie!  It resumes right where it left off! (if there's a client crash) if the user closes it, the item is removed to help memory consumption (haha PUN!)
       RETURN 0
ENDIF

NEWITEM i_memoryGame
IF <ISNUM <ARGV[0]>>
       NEW.MOREY <ARGV[0]>
       NEW.TAG.onWinFunction <ARGV[1]>
       NEW.TAG.onLoseFunction <ARGV[2]>
ELSE
       NEW.MOREY <DEF.memoryGame_maxFails>
       NEW.TAG.onWinFunction <ARGV[0]>
       NEW.TAG.onLoseFunction <ARGV[1]>
ENDIF

// this whole code section that randomizes the list using a container (linked list)
// is going to be replaced/updated as soon as I come up with something better... feel free to give me suggestions
OBJ <NEW.UID>
NEWITEM i_bag
OBJ.LINK <NEW.UID>
FOR 24
       IF <LOCAL._FOR> == memoryGame_backSide - memoryGame_iconStart   // evaluation order is right to left remember, so this is valid :P (death to paranthesis! :P) This actually helps remind me of when paranthesis *are* required and I wouldn't expect them to be (like the fact that 3 * 2 + 4 = 18 in Sphere, 10 elsewhere)
               LOCAL._FOR memoryGame_backSideSubstitute - memoryGame_iconStart
       ENDIF
       NEWITEM i_deed  // non stackable... this is a lame method, find something better :p
       NEW.MOREZ <LOCAL._FOR>
       NEW.CONT <OBJ.LINK>
       NEWITEM i_deed
       NEW.MOREZ <LOCAL._FOR>
       NEW.CONT <OBJ.LINK>
ENDFOR
WHILE <OBJ.LINK.RESCOUNT>       // here we randomly remove an item from the container, until they're all gone...
       NEW <OBJ.LINK.FINDCONT.<EVAL {0 (<OBJ.LINK.RESCOUNT> - 1)}>.UID>
       TRY OBJ.TAG.card<OBJ.LINK.RESCOUNT> <NEW.MOREZ>
       NEW.REMOVE
ENDWHILE
OBJ.LINK.REMOVE
OBJ.LINK        // wouldn't want "bad link" console errors :)
OBJ.CONT <UID>

OBJ.DIALOG d_memoryGame

[DIALOG d_memoryGame]
70,40
SRC.DIALOGCLOSE d_memoryGame -1 // sounds like in versions set not to fire a button press (0 default) when closing via script command this -1 isn't needed
resizepic 0 0 3600 659 520
dtext 160 15 481 6 * 8 Memory!     <MOREX> Matches     <MOREY> Moves Left
dorigin -65 35

FOR 6   // rows
       LOCAL.row <LOCAL._FOR>
       FOR 8   // columns
               LOCAL.index ((<LOCAL.row> - 1) * 8) + <LOCAL._FOR>
               IF <TAG.card<EVAL <LOCAL.index>>> & 020 // if the card is flipped
                       gumppic *80 +0 ((<TAG.card<EVAL <LOCAL.index>>> & ~020) + <DEF.memoryGame_iconStart>)
               ELSE
                       button *80 +0 <DEF.memoryGame_backSide> <DEF.memoryGame_backSide> 1 0 <LOCAL.index>
               ENDIF
       ENDFOR
       dorigin -65 *80
ENDFOR

[DIALOG d_memoryGame BUTTON]
ON 0
       REMOVE  // this is *NICE*... the item need not stick around when the player purposefully closes the dialog, so there won't be tons of permanent tags on players!
ON 1 48
       IF <TIMER> > -1
               DIALOG d_memoryGame
               RETURN 0
       ENDIF

       TRY TAG.card<ARGN1> <TAG.card<ARGN1>> | 020     // flip the card
       IF !<MOREZ>     // no card flipped
               MOREZ <ARGN1>   // set first card flipped
       ELIF <TAG.card<MOREZ>> == <TAG.card<ARGN1>>             // match
               MOREZ
               MOREX += 1      // increment matches
               IF <MOREX> == 24        // won
                       TIMER 1
               ELSE
                       SRC.SYSMESSAGE @1153 Match!
               ENDIF
       ELSE                                                    // failed
               MOREM <ARGN1>   // set the second card here so the timer can flip it back over... only use of reference to second card
               TIMERD 5
       ENDIF
       DIALOG d_memoryGame


[eof]

[Image: 2nis46r.jpg]
10-07-2013 02:52 AM
Visit this user's website Find all posts by this user Like Post Quote this message in a reply
Rattlehead
Master
**

Posts: 290
Likes Given: 3
Likes Received: 8 in 6 posts
Joined: Jun 2012
Reputation: 8



Post: #2
RE: Swindler's Memory Game
wow, this goes wayyyy back

[Image: matts_siggy.gif]
10-07-2013 06:12 AM
Find all posts by this user Like Post Quote this message in a reply
Mordaunt
Super Moderator
****

Posts: 1,237
Likes Given: 26
Likes Received: 55 in 43 posts
Joined: Mar 2012
Reputation: 35



Post: #3
RE: Swindler's Memory Game
yeah it does... Swindler used to have some nice scripts out.

[Image: 2nis46r.jpg]
10-07-2013 06:23 AM
Visit this user's website Find all posts by this user Like Post Quote this message in a reply
Post Reply 


Forum Jump:


User(s) browsing this thread: 1 Guest(s)