Tic Tac Toe

De DigiWiki.

// One-Prim Noughts and Crosses - OpenSim LSL script by Warin Cascabel (26 February 2009)
// 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 = 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 = 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
{
    state_entry()  // Start the game.
    {
        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.
    }
}
Outils personnels
  • Cette page a été consultée 1 370 fois.
donate
Google Ads