Tic Tac Toe
De DigiWiki.
(Différences entre les versions)
Ligne 1 : | Ligne 1 : | ||
<lsl> | <lsl> | ||
// One-Prim Noughts and Crosses - OpenSim LSL script by Warin Cascabel (26 February 2009) | // 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. | // As this script makes use of OpenSim-specific extensions to the Linden Scripting Language. | ||
// This script will NOT work in Second Life. | // This script will NOT work in Second Life. | ||
// Internal variables. | // Internal variables. | ||
- | list Spaces = [-1,-1,-1,-1,-1,-1,-1,-1,-1]; | + | 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; | + | integer GameOver = 0; // If nonzero, signals which row, column or diagonal has the win (or -1 for a draw) |
- | integer WhoseTurn = 1; | + | integer WhoseTurn = 1; // Whose turn is it next? 0=O, 1=X |
// DrawBoard() | // DrawBoard() | ||
Ligne 15 : | Ligne 13 : | ||
DrawBoard() | DrawBoard() | ||
{ | { | ||
- | string dl; | + | string dl; // holds the draw list |
- | integer i; | + | integer i; // iterator for our for loop |
- | integer x; | + | integer x; // holds the horizontal coordinate of each space |
- | integer y; | + | integer y; // holds the vertical coordinate of each space |
- | dl = osSetPenColor("", "white" ); | + | dl = osSetPenColor("", "white" ); // Set the background to solid white |
dl = osMovePen( dl, 0, 0 ); | dl = osMovePen( dl, 0, 0 ); | ||
dl = osDrawFilledRectangle( dl, 128, 128 ); | dl = osDrawFilledRectangle( dl, 128, 128 ); | ||
- | dl = osSetPenColor( dl, "black" ); | + | dl = osSetPenColor( dl, "black" ); // Draw the grid in black |
dl = osSetPenSize( dl, 2 ); | dl = osSetPenSize( dl, 2 ); | ||
dl = osDrawLine( dl, 43, 3, 43, 125 ); | dl = osDrawLine( dl, 43, 3, 43, 125 ); | ||
Ligne 29 : | Ligne 27 : | ||
dl = osDrawLine( dl, 3, 43, 125, 43 ); | dl = osDrawLine( dl, 3, 43, 125, 43 ); | ||
dl = osDrawLine( dl, 3, 86, 125, 86 ); | dl = osDrawLine( dl, 3, 86, 125, 86 ); | ||
- | dl = osSetPenSize( dl, 6 ); | + | dl = osSetPenSize( dl, 6 ); // Increase the pen size for our Xs and Os. |
- | for (i = 0; i < 9; ++i) | + | for (i = 0; i < 9; ++i) // For each element in the Spaces list: |
{ | { | ||
- | integer who = llList2Integer( Spaces, i ); | + | integer who = llList2Integer( Spaces, i ); // Get its value |
- | if (who > -1) | + | if (who > -1) // Do nothing if it's -1 (empty) |
{ | { | ||
- | x = (i % 3) * 43 + 21; | + | x = (i % 3) * 43 + 21; // Calculate the center of the square |
y = (i / 3) * 43 + 21; | y = (i / 3) * 43 + 21; | ||
- | if (who == 0) | + | if (who == 0) // If it's an O: |
{ | { | ||
- | dl = osSetPenColour( dl, "lime" ); | + | dl = osSetPenColour( dl, "lime" ); // Select a bright green pen color |
- | dl = osMovePen( dl, x-17, y-17 ); | + | dl = osMovePen( dl, x-17, y-17 ); // Move the pen to the upper left corner of the square |
- | dl = osDrawEllipse( dl, 35, 35 ); | + | dl = osDrawEllipse( dl, 35, 35 ); // Draw the O |
} | } | ||
else // If it's an X: | else // If it's an X: | ||
Ligne 55 : | Ligne 53 : | ||
if (GameOver > 0) // if GameOver is 1 or more, we will draw a red line through the winning row, column or diagonal | 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" ); | + | dl = osSetPenColor( dl, "orangered" ); // Select an orange-red color |
- | if (GameOver == 1) dl = osDrawLine( dl, 5, 21, 125, 21 ); | + | 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 ); | + | 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 ); | + | 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 ); | + | 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 == 5) dl = osDrawLine( dl, 64, 3, 64, 125 ); | ||
else if (GameOver == 6) dl = osDrawLine( dl, 107, 3, 107, 125 ); | else if (GameOver == 6) dl = osDrawLine( dl, 107, 3, 107, 125 ); | ||
Ligne 99 : | Ligne 97 : | ||
default | default | ||
{ | { | ||
- | state_entry() | + | state_entry() // Start the game. |
{ | { | ||
DrawBoard(); // Draw an empty board. | DrawBoard(); // Draw an empty board. | ||
Ligne 109 : | Ligne 107 : | ||
touch_start( integer numTouchers ) | touch_start( integer numTouchers ) | ||
{ | { | ||
- | if (llDetectedTouchFace( 0 ) != 1) return; | + | if (llDetectedTouchFace( 0 ) != 1) return; // Only accept touches from the "front" face. |
- | if (GameOver) llResetScript(); | + | if (GameOver) llResetScript(); // If the game's over, start a new one. |
- | vector v = llDetectedTouchST( 0 ); | + | 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. | 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 (llList2Integer( Spaces, index ) >= 0) return; // If space is already filled, ignore touch. |
- | Spaces = llListReplaceList( Spaces, [ WhoseTurn ], index, index ); | + | Spaces = llListReplaceList( Spaces, [ WhoseTurn ], index, index ); // Set the value of the space to X or O. |
- | WhoseTurn = 1 - WhoseTurn; | + | WhoseTurn = 1 - WhoseTurn; // Swap whose turn it will be next. |
- | GameOver = CheckForWin(); | + | GameOver = CheckForWin(); // See if anybody won yet |
- | DrawBoard(); | + | DrawBoard(); // Draw the new board. |
} | } | ||
} | } | ||
</lsl> | </lsl> |
Version du 7 octobre 2012 à 10:51
// 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 = 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 = 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. } }