Change font size
It is currently Sat Dec 15, 2018 1:12 pm

Forum rules


{L_IMAGE}



Post a new topicPost a reply Page 1 of 1   [ 9 posts ]
Author Message
 Post subject: One-Prim Noughts and Crosses (tic-tac-toe)
PostPosted: Fri Feb 27, 2009 5:29 pm 
Site Admin
User avatar

Joined: Wed Jul 16, 2008 7:22 pm
Posts: 186
The following script started as an experiment with the llDetectedTouchFace() and llDetectedTouchST() functions, and turned into a two-player Tic-Tac-Toe game using a single prim for both display and user interaction. It uses the two aforenamed functions to determine exactly where on the prim the players have touched, and several of the OpenSim-specific dynamic texture functions to draw the game board and markers.

For best results, drop this script into a cube with the color of face 1 set to white, and every other face set to black, to make it obvious which face is the playing surface (since the dynamic texture is applied to every face on the prim). Ideally, the cube's X and Z dimensions should be identical, and it should be much thinner in the Y dimension (I used a cube scaled to <1.0, 0.05, 1.0>).

There's room for improvement - especially in the CheckForWin() function, which is a horrible kludge - but it works well enough for what it is. I don't recommend trying to play the game while your client is still downloading texture assets from the region, as that seriously hampers the display of the dynamic textures.

{L_CODE}:
// One-Prim Noughts and Crosses - OpenSim LSL script by Warin Cascabel (26 February 2009)
//
// Please note: as this script makes use of OpenSim-specific extensions to the Linden Scripting
//              Language, this script will NOT work in Second Life.


// Internal variables.
//
list Spaces = [-1,-1,-1,-1,-1,-1,-1,-1,-1];    // Keeps track of what's in which space of the board. -1=empty, 0=O, 1=X
integer GameOver = 0;      // If nonzero, signals which row, column or diagonal has the win (or -1 for a draw)
integer WhoseTurn = 1;     // Whose turn is it next? 0=O, 1=X

// DrawBoard() - builds the dynamic texture command based on the contents of the Spaces list and the
//               GameOver variable.
//
DrawBoard()
{
    string dl;                                   // holds the draw list
    integer i;                                   // iterator for our for loop
    integer x;                                   // holds the horizontal coordinate of each space
    integer y;                                   // holds the vertical coordinate of each space
    dl = osSetPenColour("", "white" );           // Set the background to solid white
    dl = osMovePen( dl, 0, 0 );
    dl = osDrawFilledRectangle( dl, 128, 128 );
    dl = osSetPenColour( dl, "black" );          // Draw the grid in black
    dl = osSetPenSize( dl, 2 );
    dl = osDrawLine( dl, 43, 3, 43, 125 );
    dl = osDrawLine( dl, 86, 3, 86, 125 );
    dl = osDrawLine( dl, 3, 43, 125, 43 );
    dl = osDrawLine( dl, 3, 86, 125, 86 );
    dl = osSetPenSize( dl, 6 );                  // Increase the pen size for our Xs and Os.
    for (i = 0; i < 9; ++i)                      // For each element in the Spaces list:
    {
        integer who = llList2Integer( Spaces, i ); // Get its value
        if (who > -1)                              // Do nothing if it's -1 (empty)
        {
            x = (i % 3) * 43 + 21;                 // Calculate the center of the square
            y = (i / 3) * 43 + 21;
            if (who == 0)                          // If it's an O:
            {
                dl = osSetPenColour( dl, "lime" ); // Select a bright green pen color
                dl = osMovePen( dl, x-17, y-17 );  // Move the pen to the upper left corner of the square
                dl = osDrawEllipse( dl, 35, 35 );  // Draw the O
            }
            else                                   // If it's an X:
            {
                dl = osSetPenColour( dl, "blue" );              // Select a bright blue pen color
                dl = osDrawLine( dl, x-17, y-17, x+17, y+17 );  // Draw the first line of the X
                dl = osDrawLine( dl, x-17, y+17, x+17, y-17 );  // Draw the second line of the X
            }
        }
    }
    if (GameOver > 0) // if GameOver is 1 or more, we will draw a red line through the winning row, column or diagonal
    {
        dl = osSetPenColour( dl, "orangered" );                             // Select an orange-red color
        if (GameOver == 1) dl = osDrawLine( dl, 5, 21, 125, 21 );           // Draw a horizontal, vertical or diagonal line,
        else if (GameOver == 2) dl = osDrawLine( dl, 3, 64, 125, 64 );      // based on the value of GameOver. This is
        else if (GameOver == 3) dl = osDrawLine( dl, 3, 107, 125, 107 );    // really kind of kludgy, but it gets the job
        else if (GameOver == 4) dl = osDrawLine( dl, 21, 3, 21, 125 );      // done.
        else if (GameOver == 5) dl = osDrawLine( dl, 64, 3, 64, 125 );
        else if (GameOver == 6) dl = osDrawLine( dl, 107, 3, 107, 125 );
        else if (GameOver == 7) dl = osDrawLine( dl, 3, 3, 125, 125 );
        else if (GameOver == 8) dl = osDrawLine( dl, 125, 3, 3, 125 );
    }
    osSetDynamicTextureData( "", "vector", dl, "width:128,height:128,alpha:false", 0 ); // Draw the dynamic texture
}

// CheckForWin() - returns an integer value of -1 for a draw, 0 if there are still moves that can be made, or a positive
//                 integer specifying which row, column or diagonal contains the win. This is REALLY kludgy.
//
integer CheckForWin()
{
    integer s1 = llList2Integer( Spaces, 0 ); // Get each space's value into its own integer for use in the tests below,
    integer s2 = llList2Integer( Spaces, 1 ); // which calls llList2Integer() 9 times (instead of the 33 times that it
    integer s3 = llList2Integer( Spaces, 2 ); // would take to call the function for each space in the tests below).
    integer s4 = llList2Integer( Spaces, 3 );
    integer s5 = llList2Integer( Spaces, 4 );
    integer s6 = llList2Integer( Spaces, 5 );
    integer s7 = llList2Integer( Spaces, 6 );
    integer s8 = llList2Integer( Spaces, 7 );
    integer s9 = llList2Integer( Spaces, 8 );
   
    if ((s1 != -1) && (s1 == s2) && (s1 == s3)) return 1; // Top row
    if ((s4 != -1) && (s4 == s5) && (s4 == s6)) return 2; // Middle row
    if ((s7 != -1) && (s7 == s8) && (s7 == s9)) return 3; // Bottom row
    if ((s1 != -1) && (s1 == s4) && (s1 == s7)) return 4; // Left column
    if ((s2 != -1) && (s2 == s5) && (s2 == s8)) return 5; // Middle column
    if ((s3 != -1) && (s3 == s6) && (s3 == s9)) return 6; // Right column
    if ((s1 != -1) && (s1 == s5) && (s1 == s9)) return 7; // Top left to bottom right
    if ((s3 != -1) && (s3 == s5) && (s3 == s7)) return 8; // Top right to bottom left
   
    if ((s1 == -1) || (s2 == -1) || (s3 == -1) || (s4 == -1) || (s5 == -1) ||
        (s6 == -1) || (s7 == -1) || (s8 == -1) || (s9 == -1)) return 0; // At least one space is open
    return -1; // No more moves can be made, but nobody won.
}


default
{
    // Start the game.
    //
    state_entry()
    {
        DrawBoard(); // Draw an empty board.
    }
   
    // The actual game logic all happens in touch_start(). It retrieves the coordinates of where on the front face the user
    // touched, and from that calculates which space was touched. If it's empty, it fills it in with an X or an O, depending
    // on whose turn it is, checks to see if there's a winner, and redraws the game board.
    //
    touch_start( integer numTouchers )
    {
        if (llDetectedTouchFace( 0 ) != 1) return;                             // Only accept touches from the "front" face.
        if (GameOver) llResetScript();                                         // If the game's over, start a new one.
        vector v = llDetectedTouchST( 0 );                                     // Get X,Y coords of the touch on the face.
        integer index = llFloor( v.x * 3.0 ) + (3 * llFloor( (1-v.y) * 3.0 )); // Turn that into index into the Spaces list.
        if (llList2Integer( Spaces, index ) >= 0) return;                      // If space is already filled, ignore touch.
        Spaces = llListReplaceList( Spaces, [ WhoseTurn ], index, index );     // Set the value of the space to X or O.
        WhoseTurn = 1 - WhoseTurn;                                             // Swap whose turn it will be next.
        GameOver = CheckForWin();                                              // See if anybody won yet
        DrawBoard();                                                           // Draw the new board.
    }
}


Top
 Profile  
 
 Post subject: Re: One-Prim Noughts and Crosses (tic-tac-toe)
PostPosted: Mon Mar 09, 2009 9:45 pm 
Furious Typer
User avatar

Joined: Fri Jan 16, 2009 12:19 am
Posts: 58
Location: Orlando, FL - USA
Wow, cool tic-tac-toe and all, but I have a silly question in general...

Where exactly did you learn of the names of colors (e.g. "lime", "orangered") which are recognized by osDynamicTexture?
I would not have guested those particular ones in a million years.

Perhaps that raises another silly question if not to stray too far...
Why would it not use hex code e.g. 0xffffff or #ffffff = white etc. or some other more accessible nomenclature?

I searched high and low (with the exception of peering into the code) and to no avail. :D

Thanks in advance,
-Nolo

_________________
Within the great calm exists an even greater fury waiting to be unleashed with effortless intent.


Top
 Profile  
 
 Post subject: Re: One-Prim Noughts and Crosses (tic-tac-toe)
PostPosted: Mon Mar 09, 2009 11:24 pm 
Furious Typer
User avatar

Joined: Fri Jan 16, 2009 12:19 am
Posts: 58
Location: Orlando, FL - USA
{L_CODE}:
integer CheckForWin()
{
    // there are space(s) open
    // this rules out any combination of [1, -1, 0] adding up to an owin below
    if (~llListFindList(Spaces, [-1]))
        return 0;
   
    // add up the rows, columns & diagonals for each possible win
    float top = llListStatistics(LIST_STAT_SUM, llList2List(Spaces, 0, 2));
    float midrow = llListStatistics(LIST_STAT_SUM, llList2List(Spaces, 3, 5));
    float bottom = llListStatistics(LIST_STAT_SUM, llList2List(Spaces, 6, 8));
    float left = llListStatistics(LIST_STAT_SUM, llList2ListStrided(Spaces, 3, 0, -1));
    float midcol = llListStatistics(LIST_STAT_SUM, llList2ListStrided(Spaces, 3, 1, -1));
    float right = llListStatistics(LIST_STAT_SUM, llList2ListStrided(Spaces, 3, 2, -1));
    float leftdiag = llListStatistics(LIST_STAT_SUM, llList2ListStrided(Spaces, 4, 0, -1));
    float rightdiag = llListStatistics(LIST_STAT_SUM, llList2ListStrided(Spaces, 2, 2, 6));
   
    // put them back in a list to search for summations that qualify as a win
    list checkall = [top, midrow, bottom, left, midcol, right, leftdiag, rightdiag];
    float xwin = llListStatistics(LIST_STAT_MAX, checkall);
    float owin = llListStatistics(LIST_STAT_MIN, checkall);
   
    // any sum of [1, 1, 1] qualifies x as winner
    if (xwin == 3.)
        return llListFindList(checkall, [xwin]) + 1;
   
    // any sum of [0, 0, 0] qualifies o as a winner
    if (owin == 0.)
        return llListFindList(checkall, [owin]) + 1;
   
    // anything else is a stalemate
    return -1;
}


This may work, but I haven't tested...

The "return llListFindList(checkall, [..]) + 1;" will return the same enumerated values as the original function

Best Regards,
-Nolo

_________________
Within the great calm exists an even greater fury waiting to be unleashed with effortless intent.


Top
 Profile  
 
 Post subject: Re: One-Prim Noughts and Crosses (tic-tac-toe)
PostPosted: Tue Mar 10, 2009 8:39 pm 
Furious Typer
User avatar

Joined: Fri Jan 16, 2009 12:19 am
Posts: 58
Location: Orlando, FL - USA
Meh... I thought about it and this way makes more sense

{L_CODE}:
integer CheckForWin()
{
    string tokens = "ox ";  // index of possible tokens at any position on the board
    list board;             // 'Spaces' list translated to string tokens
    integer i;
    integer move;           // the index of the token at 'i' position on the board (Spaces)
    for (i=0;i<9;i++)
    {
        // translate Spaces list to a string containing x's, o's and blank spaces
        move = llList2Integer(Spaces, i);
        board += [llGetSubString(tokens, move, move)];
    }
   
    string top = llDumpList2String(llList2List(Spaces, 0, 2), "");
    string midrow = llDumpList2String(llList2List(Spaces, 3, 5), "");
    string bottom = llDumpList2String(llList2List(Spaces, 6, 8), "");
    string left = llDumpList2String(llList2ListStrided(Spaces, 3, 0, -1), "");
    string midcol = llDumpList2String(llList2ListStrided(Spaces, 3, 1, -1), "");
    string right = llDumpList2String(llList2ListStrided(Spaces, 3, 2, -1), "");
    string leftdiag = llDumpList2String(llList2ListStrided(Spaces, 4, 0, -1), "");
    string rightdiag = llDumpList2String(llList2ListStrided(Spaces, 2, 2, 6), "");
   
    // put them back in a list to search for qualifiers
    list checkall = [top, midrow, bottom, left, midcol, right, leftdiag, rightdiag];
    integer xwin = llListFindList(checkall, ["xxx"]);
    integer owin = llListFindList(checkall, ["ooo"]);
    integer stalemate = llListFindList(board, [" "]);
   
    // found a row, col or diagonal filled with "xxx"
    if (~xwin)
        return xwin + 1;
   
    // found a row, col or diagonal filled with "ooo"
    if (~owin)
        return owin + 1;
   
    // if nobody has won and there are no spaces left on the board then it's a stalemate
    if (!~staleMate)
        return -1;
   
    // otherwise nothing qualifies yet
    return 0;
}


The other function I posted would force players to continue if there are any spaces left on the board.

This one actually checks all outcomes and returns the correct one.

Best Regards,
-Nolo

_________________
Within the great calm exists an even greater fury waiting to be unleashed with effortless intent.


Top
 Profile  
 
 Post subject: Re: One-Prim Noughts and Crosses (tic-tac-toe)
PostPosted: Wed Mar 11, 2009 7:28 am 
Site Admin
User avatar

Joined: Wed Jul 16, 2008 7:22 pm
Posts: 186
Nolo {L_WROTE}:
Wow, cool tic-tac-toe and all, but I have a silly question in general...

Where exactly did you learn of the names of colors (e.g. "lime", "orangered") which are recognized by osDynamicTexture?
I would not have guested those particular ones in a million years.

Those are from the list of named .NET colors:

http://www.opinionatedgeek.com/DotNet/Tools/Colors/default.aspx

{L_QUOTE}:
Why would it not use hex code e.g. 0xffffff or #ffffff = white etc. or some other more accessible nomenclature?

I tried doing that, a while back; didn't seem to work. Since the examples in the OpenSim wiki showed named colors, I went hunting for others, and found the above list.

{L_QUOTE}:
This may work, but I haven't tested...

{L_QUOTE}:
Meh... I thought about it and this way makes more sense

You know, I forgot all about the list statistics functions. Thanks! I'll give that a try when I get back inworld, but I suspect it will need to be modified slightly, as llList2ListStrided() only returns the first item of each complete stride, even if your starting index is elsewhere in the stride. Assuming the functions behave the same way in OpenSim as they do in SL, of course.


Top
 Profile  
 
 Post subject: Re: One-Prim Noughts and Crosses (tic-tac-toe)
PostPosted: Wed Mar 11, 2009 7:27 pm 
Furious Typer
User avatar

Joined: Fri Jan 16, 2009 12:19 am
Posts: 58
Location: Orlando, FL - USA
Heh,

{L_QUOTE}:
You know, I forgot all about the list statistics functions. Thanks!


Much appreciated on your replies, Thanks! That list comes in handily.
Not sure about llStrided, but I couldn't test because even the LL viewer didn't seem to like the llDetectedtouch() functions. I'll be updating revision soon though...

Please pardon, but there are a couple other questions which have begun to nag at me...

Have you considered trying to make the game play back? e.g. user vs. machine - If you have I wouldn't mind giving it a try as well.

But this one is the real issue...
What about a simple (VERY simple, but something that could for all purposes appear to try and trick or distract the opponent, but still recover with an objective) machine learning algorithm for something a little meatier say up to 8x8 board (would be up to 64 positions to score)... do you think that would be possible here?

I wonder if that would be worth doing, and I apologize as I haven't researched it, but if the ultimate outcome of a master player is a matter of who goes first (which if I recall in this case I think that it is) then would a script be able to figure out how to play that well??

I look forward to your reply. :)

Best Regards,
-Nolo

_________________
Within the great calm exists an even greater fury waiting to be unleashed with effortless intent.


Top
 Profile  
 
 Post subject: Re: One-Prim Noughts and Crosses (tic-tac-toe)
PostPosted: Mon Mar 16, 2009 7:37 pm 
Site Admin
User avatar

Joined: Wed Jul 16, 2008 7:22 pm
Posts: 186
Nolo {L_WROTE}:
I couldn't test because even the LL viewer didn't seem to like the llDetectedtouch() functions. I'll be updating revision soon though...


Yeah, those functions are relatively recent.

{L_QUOTE}:
Have you considered trying to make the game play back? e.g. user vs. machine - If you have I wouldn't mind giving it a try as well.

Go for it!

{L_QUOTE}:
What about a simple (VERY simple, but something that could for all purposes appear to try and trick or distract the opponent, but still recover with an objective) machine learning algorithm for something a little meatier say up to 8x8 board (would be up to 64 positions to score)... do you think that would be possible here?

Honestly, I'm not sure what the limitations of LSL are here.

{L_QUOTE}:
if the ultimate outcome of a master player is a matter of who goes first (which if I recall in this case I think that it is) then would a script be able to figure out how to play that well??

If both players make no mistakes, the game will result in a draw every time. There's a fairly concise description of the move priorities in the Wikipedia entry on Tic-tac-toe. Given that early computers with less memory even than an SL LSL script were able to play tic-tac-toe against a human, I'm sure it's not impossible.


Top
 Profile  
 
 Post subject: Re: One-Prim Noughts and Crosses (tic-tac-toe)
PostPosted: Mon Mar 16, 2009 8:42 pm 
Furious Typer
User avatar

Joined: Fri Jan 16, 2009 12:19 am
Posts: 58
Location: Orlando, FL - USA
Cool, cool,

I shall do my worst! :D

Let y'all know how it turns out.

Best Regards,
-Nolo

_________________
Within the great calm exists an even greater fury waiting to be unleashed with effortless intent.


Top
 Profile  
 
 Post subject: Re: One-Prim Noughts and Crosses (tic-tac-toe)
PostPosted: Wed Apr 25, 2018 12:02 pm 

Joined: Fri Jul 28, 2017 8:30 am
Posts: 3
For anyone that wants this script still it was throwing a error when i tried it on my grid so changed it so it would not throw the script error out :) Saves others having to do it :)

// One-Prim Noughts and Crosses - OpenSim LSL script by Warin Cascabel (26 February 2009)
//
// Please note: as this script makes use of OpenSim-specific extensions to the Linden Scripting
// Language, this script will NOT work in Second Life.


// Internal variables.
//
list Spaces = [-1,-1,-1,-1,-1,-1,-1,-1,-1]; // Keeps track of what's in which space of the board. -1=empty, 0=O, 1=X
integer GameOver = 0; // If nonzero, signals which row, column or diagonal has the win (or -1 for a draw)
integer WhoseTurn = 1; // Whose turn is it next? 0=O, 1=X

// DrawBoard() - builds the dynamic texture command based on the contents of the Spaces list and the
// GameOver variable.
//
DrawBoard()
{
string dl; // holds the draw list
integer i; // iterator for our for loop
integer x; // holds the horizontal coordinate of each space
integer y; // holds the vertical coordinate of each space
dl = osSetPenColor("", "white" ); // Set the background to solid white
dl = osMovePen( dl, 0, 0 );
dl = osDrawFilledRectangle( dl, 128, 128 );
dl = osSetPenColor( dl, "black" ); // Draw the grid in black
dl = osSetPenSize( dl, 2 );
dl = osDrawLine( dl, 43, 3, 43, 125 );
dl = osDrawLine( dl, 86, 3, 86, 125 );
dl = osDrawLine( dl, 3, 43, 125, 43 );
dl = osDrawLine( dl, 3, 86, 125, 86 );
dl = osSetPenSize( dl, 6 ); // Increase the pen size for our Xs and Os.
for (i = 0; i < 9; ++i) // For each element in the Spaces list:
{
integer who = llList2Integer( Spaces, i ); // Get its value
if (who > -1) // Do nothing if it's -1 (empty)
{
x = (i % 3) * 43 + 21; // Calculate the center of the square
y = (i / 3) * 43 + 21;
if (who == 0) // If it's an O:
{
dl = osSetPenColor( dl, "lime" ); // Select a bright green pen color
dl = osMovePen( dl, x-17, y-17 ); // Move the pen to the upper left corner of the square
dl = osDrawEllipse( dl, 35, 35 ); // Draw the O
}
else // If it's an X:
{
dl = osSetPenColor( dl, "blue" ); // Select a bright blue pen color
dl = osDrawLine( dl, x-17, y-17, x+17, y+17 ); // Draw the first line of the X
dl = osDrawLine( dl, x-17, y+17, x+17, y-17 ); // Draw the second line of the X
}
}
}
if (GameOver > 0) // if GameOver is 1 or more, we will draw a red line through the winning row, column or diagonal
{
dl = osSetPenColor( dl, "orangered" ); // Select an orange-red color
if (GameOver == 1) dl = osDrawLine( dl, 5, 21, 125, 21 ); // Draw a horizontal, vertical or diagonal line,
else if (GameOver == 2) dl = osDrawLine( dl, 3, 64, 125, 64 ); // based on the value of GameOver. This is
else if (GameOver == 3) dl = osDrawLine( dl, 3, 107, 125, 107 ); // really kind of kludgy, but it gets the job
else if (GameOver == 4) dl = osDrawLine( dl, 21, 3, 21, 125 ); // done.
else if (GameOver == 5) dl = osDrawLine( dl, 64, 3, 64, 125 );
else if (GameOver == 6) dl = osDrawLine( dl, 107, 3, 107, 125 );
else if (GameOver == 7) dl = osDrawLine( dl, 3, 3, 125, 125 );
else if (GameOver == 8) dl = osDrawLine( dl, 125, 3, 3, 125 );
}
osSetDynamicTextureData( "", "vector", dl, "width:128,height:128,alpha:false", 0 ); // Draw the dynamic texture
}

// CheckForWin() - returns an integer value of -1 for a draw, 0 if there are still moves that can be made, or a positive
// integer specifying which row, column or diagonal contains the win. This is REALLY kludgy.
//
integer CheckForWin()
{
integer s1 = llList2Integer( Spaces, 0 ); // Get each space's value into its own integer for use in the tests below,
integer s2 = llList2Integer( Spaces, 1 ); // which calls llList2Integer() 9 times (instead of the 33 times that it
integer s3 = llList2Integer( Spaces, 2 ); // would take to call the function for each space in the tests below).
integer s4 = llList2Integer( Spaces, 3 );
integer s5 = llList2Integer( Spaces, 4 );
integer s6 = llList2Integer( Spaces, 5 );
integer s7 = llList2Integer( Spaces, 6 );
integer s8 = llList2Integer( Spaces, 7 );
integer s9 = llList2Integer( Spaces, 8 );

if ((s1 != -1) && (s1 == s2) && (s1 == s3)) return 1; // Top row
if ((s4 != -1) && (s4 == s5) && (s4 == s6)) return 2; // Middle row
if ((s7 != -1) && (s7 == s8) && (s7 == s9)) return 3; // Bottom row
if ((s1 != -1) && (s1 == s4) && (s1 == s7)) return 4; // Left column
if ((s2 != -1) && (s2 == s5) && (s2 == s8)) return 5; // Middle column
if ((s3 != -1) && (s3 == s6) && (s3 == s9)) return 6; // Right column
if ((s1 != -1) && (s1 == s5) && (s1 == s9)) return 7; // Top left to bottom right
if ((s3 != -1) && (s3 == s5) && (s3 == s7)) return 8; // Top right to bottom left

if ((s1 == -1) || (s2 == -1) || (s3 == -1) || (s4 == -1) || (s5 == -1) ||
(s6 == -1) || (s7 == -1) || (s8 == -1) || (s9 == -1)) return 0; // At least one space is open
return -1; // No more moves can be made, but nobody won.
}


default
{
// Start the game.
//
state_entry()
{
DrawBoard(); // Draw an empty board.
}

// The actual game logic all happens in touch_start(). It retrieves the coordinates of where on the front face the user
// touched, and from that calculates which space was touched. If it's empty, it fills it in with an X or an O, depending
// on whose turn it is, checks to see if there's a winner, and redraws the game board.
//
touch_start( integer numTouchers )
{
if (llDetectedTouchFace( 0 ) != 1) return; // Only accept touches from the "front" face.
if (GameOver) llResetScript(); // If the game's over, start a new one.
vector v = llDetectedTouchST( 0 ); // Get X,Y coords of the touch on the face.
integer index = llFloor( v.x * 3.0 ) + (3 * llFloor( (1-v.y) * 3.0 )); // Turn that into index into the Spaces list.
if (llList2Integer( Spaces, index ) >= 0) return; // If space is already filled, ignore touch.
Spaces = llListReplaceList( Spaces, [ WhoseTurn ], index, index ); // Set the value of the space to X or O.
WhoseTurn = 1 - WhoseTurn; // Swap whose turn it will be next.
GameOver = CheckForWin(); // See if anybody won yet
DrawBoard(); // Draw the new board.
}
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Post a new topicPost a reply Page 1 of 1   [ 9 posts ]


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
610nm Style by Daniel St. Jules of Gamexe.net