You are on page 1of 10

GraphicsWindow.KeyDown = HandleKey GraphicsWindow.BackgroundColor = GraphicsWindow.

GetColorFromRGB( 253, 252, 251 ) While "True" BOXES = 4 ' number of boxes per piece BWIDTH = 25 ' box width in pixels XOFFSET = 40 ' Screen X offset in pixels of where the board starts YOFFSET = 40 ' Screen Y offset in pixels of where the board starts CWIDTH = 10 ' Canvas Width, in number of boxes CHEIGHT = 20 ' Canvas Height, in number of boxes. STARTDELAY = 800 ENDDELAY = 175 PREVIEW_xpos = 13 PREVIEW_ypos = 2 GraphicsWindow.Clear() GraphicsWindow.Title = "Small Basic Tetris" GraphicsWindow.Height = 580 GraphicsWindow.Width = 700 GraphicsWindow.Show() SetupTemplates() SetupCanvas() MainLoop() GraphicsWindow.ShowMessage( "Game Over", "Small Basic Tetris" ) EndWhile Sub MainLoop template = Text.Append("template", Math.GetRandomNumber(7)) CreatePiece() ' in: template ret: h nextPiece = h end = 0 sessionDelay = STARTDELAY While end = 0 If sessionDelay > ENDDELAY Then sessionDelay = sessionDelay - 1 EndIf delay = sessionDelay thisPiece = nextPiece template = Text.Append("template", Math.GetRandomNumber(7)) CreatePiece() ' in: template ret: h nextPiece = h DrawPreviewPiece() h = thisPiece ypos = 0 done = 0 xpos = 3 ' always drop from column 3 CheckStop() ' in: ypos, xpos, h ret: done If done = 1 Then ypos = ypos - 1 MovePiece() 'in: ypos, xpos, h end = 1 EndIf

yposdelta = 0 While done = 0 Or yposdelta > 0 MovePiece() 'in: ypos, xpos, h ' Delay, but break if the delay get set to 0 if the piece gets dropped delayIndex = delay While delayIndex > 0 And delay > 0 Program.Delay(10) delayIndex = delayIndex - 10 EndWhile If yposdelta > 0 Then yposdelta = yposdelta - 1 ' used to create freespin, when the piece is rotated Else ypos = ypos + 1 ' otherwise, move the piece down. EndIf ' Check if the piece should stop. CheckStop() ' in: ypos, xpos, h ret: done EndWhile EndWhile EndSub Sub HandleKey ' Stop game If GraphicsWindow.LastKey = "Escape" Then Program.End() EndIf ' Move piece left If GraphicsWindow.LastKey = "Left" Then moveDirection = -1 ValidateMove() ' in: ypos, xpos, h, moveDirection ret: invalidMove = 1 or 1 or 2 if move is invalid, otherwise 0 If invalidMove = 0 Then xpos = xpos + moveDirection EndIf MovePiece() 'in: ypos, xpos, h EndIf ' Move piece right If GraphicsWindow.LastKey = "Right" Then moveDirection = 1 ValidateMove() ' in: ypos, xpos, h, moveDirection ret: invalidMove = 1 or 1 or 2 if move is invalid, otherwise 0 If invalidMove = 0 Then xpos = xpos + moveDirection EndIf MovePiece() 'in: ypos, xpos, h EndIf ' Move piece down If GraphicsWindow.LastKey = "Down" or GraphicsWindow.LastKey = "Space" Then delay = 0 EndIf ' Rotate piece If GraphicsWindow.LastKey = "Up" Then

basetemplate = Array.GetValue(h, -1) ' Array.GetValue(h, -1) = the template name template = "temptemplate" rotation = "CW" CopyPiece() 'in basetemplate, template, rotation Array.SetValue(h, -1, template) ' Array.GetValue(h, -1) = the template name moveDirection = 0 ValidateMove() ' in: ypos, xpos, h, moveDirection ret: invalidMove = 1 or 1 or 2 if move is invalid, otherwise 0 ' See if it can be moved so that it will rotate. xposbk = xpos yposdelta = 0 While yposdelta = 0 And Math.Abs(xposbk - xpos) < 3 ' move up to 3 times onl y ' if the rotation move worked, copy the temp to "rotatedtemplate" and use that from now on If invalidMove = 0 Then basetemplate = template template = "rotatedtemplate" Array.SetValue(h, -1, template) ' Array.GetValue(h, -1) = the template n ame rotation = "COPY" CopyPiece() 'in basetemplate, template, rotation yposdelta = 1 ' Don't move down if we rotate MovePiece() 'in: ypos, xpos, h ElseIf invalidMove = 2 Then ' Don't support shifting piece when hitting another piece to the right o r left. xpos = 99 ' exit the loop Else ' if the rotated piece can't be placed, move it left or right and try ag ain. xpos = xpos - invalidMove ValidateMove() ' in: ypos, xpos, h, moveDirection ret: invalidMove = 1 or -1 or 2 if move is invalid, otherwise 0 EndIf EndWhile If invalidMove <> 0 Then xpos = xposbk Array.SetValue(h, -1, basetemplate) ' Array.GetValue(h, -1) = the template name template = "" EndIf EndIf EndSub Sub DrawPreviewPiece xpos = PREVIEW_xpos ypos = PREVIEW_ypos h = nextPiece XOFFSETBK = XOFFSET YOFFSETBK = YOFFSET XOFFSET = XOFFSET + Array.GetValue(Array.GetValue(h, -1), "pviewx") ' Array.Ge tValue(h, -1) = the template name YOFFSET = YOFFSET + Array.GetValue(Array.GetValue(h, -1), "pviewy") ' Array.Ge

tValue(h, -1) = the template name MovePiece() 'in: ypos, xpos, h XOFFSET = XOFFSETBK YOFFSET = YOFFSETBK EndSub ' creates template that's a rotated basetemplate Sub CopyPiece 'in basetemplate, template, rotation L = Array.GetValue(basetemplate, "dim") If rotation = "CW" Then For i = 0 to BOXES - 1 ' x' = y y' = L - 1 - x v = Array.GetValue(basetemplate, i) 'x = Math.Floor(v/10) 'y = Math.Remainder(v, 10) ' new x and y x = (Math.Remainder(v, 10)) y = (L - 1 - Math.Floor(v/10)) Array.SetValue(template, i, x * 10 + y) EndFor ' Count-Cockwise is not currently used ElseIf rotation = "CCW" Then For i = 0 to BOXES - 1 ' x' = L - 1 - y y' = x v = Array.GetValue(basetemplate, i) 'x = Math.Floor(v/10) 'y = Math.Remainder(v, 10) ' new x and y x = (L - 1 - Math.Remainder(v, 10)) y = Math.Floor(v/10) Array.SetValue(template, i, x * 10 + y) EndFor ElseIf rotation = "COPY" Then For i = 0 to BOXES - 1 Array.SetValue(template, i, Array.GetValue(basetemplate, i)) EndFor Else GraphicsWindow.ShowMessage("invalid parameter", "Error") Program.End() EndIf ' Copy the remain properties from basetemplate to template. Array.SetValue(template, "color", Array.GetValue(basetemplate, "color")) Array.SetValue(template, "dim", Array.GetValue(basetemplate, "dim")) Array.SetValue(template, "pviewx", Array.GetValue(basetemplate, "pviewx")) Array.SetValue(template, "pviewy", Array.GetValue(basetemplate, "pviewy")) EndSub Sub CreatePiece ' in: template ret: h ' Create a new handle, representing an arrayName, that will represent the piec e hcount = hcount + 1 h = Text.Append("piece", hcount) Array.SetValue(h, -1, template) ' Array.GetValue(h, -1) = the template name GraphicsWindow.PenWidth = 1

GraphicsWindow.PenColor = "Black" GraphicsWindow.BrushColor = Array.GetValue(template, "color") For i = 0 to BOXES - 1 s = Shapes.AddRectangle(BWIDTH, BWIDTH) Shapes.Move(s, -BWIDTH, -BWIDTH) ' move off screen Array.SetValue(h, i, s) EndFor EndSub Sub MovePiece 'in: ypos, xpos, h. ypos/xpos is 0-19, representing the top/left b ox coordinate of the piece on the canvas. h returned by CreatePiece For i = 0 to BOXES - 1 v = Array.GetValue(Array.GetValue(h, -1), i) ' Array.GetValue(h, -1) = the template name x = Math.Floor(v/10) y = Math.Remainder(v, 10) ' Array.GetValue(h, i) = box for piece h. ' xpos/ypos = are topleft of shape. x/y is the box offset within the shape. Shapes.Move(Array.GetValue(h, i), XOFFSET + xpos * BWIDTH + x * BWIDTH, YOFF SET + ypos * BWIDTH + y * BWIDTH) EndFor EndSub Sub ValidateMove ' in: ypos, xpos, h, moveDirection ret: invalidMove = 1 or -1 o r 2 if move is invalid, otherwise 0 i = 0 invalidMove = 0 While i < BOXES v = Array.GetValue(Array.GetValue(h, -1), i) ' Array.GetValue(h, -1) = the template name 'x/y is the box offset within the shape. x = Math.Floor(v/10) y = Math.Remainder(v, 10) If (x + xpos + moveDirection) < 0 Then invalidMove = -1 i = BOXES ' force getting out of the loop EndIf If (x + xpos + moveDirection) >= CWIDTH Then invalidMove = 1 i = BOXES ' force getting out of the loop EndIf If Array.GetValue("c", (x + xpos + moveDirection) + (y + ypos) * CWIDTH) <> "." Then invalidMove = 2 i = BOXES ' force getting out of the loop EndIf i = i + 1 EndWhile EndSub Sub CheckStop ' in: ypos, xpos, h ret: done done = 0

i = 0 While i < BOXES v = Array.GetValue(Array.GetValue(h, -1), i) ' Array.GetValue(h, -1) = the template name 'x/y is the box offset within the shape. x = Math.Floor(v/10) y = Math.Remainder(v, 10) If y + ypos > CHEIGHT Or Array.GetValue("c", (x + xpos) + (y + ypos) * CWIDT H) <> "." Then done = 1 i = BOXES ' force getting out of the loop EndIf i = i + 1 EndWhile ' If we need to stop the piece, move the box handles to the canvas If done = 1 Then For i = 0 to BOXES - 1 v = Array.GetValue(Array.GetValue(h, -1), i) ' Array.GetValue(h, -1) = the template name 'x = Math.Floor(v/10) 'y = Math.Remainder(v, 10) Array.SetValue("c", (Math.Floor(v/10) + xpos) + (Math.Remainder(v, 10) + y pos - 1) * CWIDTH, Array.GetValue(h, i)) EndFor ' 1 points for every piece successfully dropped score = score + 1 PrintScore() ' Delete clared lines DeleteLines() EndIf EndSub Sub DeleteLines linesCleared = 0 ' Iterate over each row, starting from the bottom For y = CHEIGHT - 1 to 0 Step -1 ' Check to see if the whole row is filled x = CWIDTH While x = CWIDTH x = 0 While x < CWIDTH piece = Array.GetValue("c", x + y * CWIDTH) If piece = "." then x = CWIDTH EndIf x = x + 1 EndWhile ' if non of them were empty (i.e "."), then remove the line. If x = CWIDTH Then

' Delete the line For x1 = 0 to CWIDTH - 1 Shapes.Remove(Array.GetValue("c", x1 + y * CWIDTH)) EndFor linesCleared = linesCleared + 1 ' Move everything else down one. For y1 = y To 1 Step -1 For x1 = 0 to CWIDTH - 1 piece = Array.GetValue("c", x1 + (y1 - 1) * CWIDTH) Array.SetValue("c", x1 + y1 * CWIDTH, piece) Shapes.Move(piece, Shapes.GetLeft(piece), Shapes.GetTop(piece) + BWI DTH) EndFor EndFor EndIf EndWhile EndFor If linesCleared > 0 Then score = score + 100 * Math.Round(linesCleared * 2.15 - 1) PrintScore() EndIf EndSub Sub SetupCanvas ' GraphicsWindow.DrawResizedImage( Flickr.GetRandomPicture( "bricks" ), 0, 0, Gr aphicsWindow.Width, GraphicsWindow.Height) GraphicsWindow.BrushColor = GraphicsWindow.BackgroundColor GraphicsWindow.FillRectangle(XOFFSET, YOFFSET, CWIDTH*BWIDTH, CHEIGHT*BWIDTH) Program.Delay(200) GraphicsWindow.PenWidth = 1 GraphicsWindow.PenColor = "Pink" For x = 0 To CWIDTH-1 For y = 0 To CHEIGHT-1 Array.SetValue("c", x + y * CWIDTH, ".") ' "." indicates spot is free GraphicsWindow.DrawRectangle(XOFFSET + x * BWIDTH, YOFFSET + y * BWIDTH, B WIDTH, BWIDTH) EndFor EndFor GraphicsWindow.PenWidth = 4 GraphicsWindow.PenColor = "Black" GraphicsWindow.DrawLine(XOFFSET, YOFFSET, XOFFSET, YOFFSET + CHEIGHT*BWIDTH) GraphicsWindow.DrawLine(XOFFSET + CWIDTH*BWIDTH, YOFFSET, XOFFSET + CWIDTH*BWI DTH, YOFFSET + CHEIGHT*BWIDTH) GraphicsWindow.DrawLine(XOFFSET, YOFFSET + CHEIGHT*BWIDTH, XOFFSET + CWIDTH*BW IDTH, YOFFSET + CHEIGHT*BWIDTH) GraphicsWindow.PenColor = "Lime" GraphicsWindow.DrawLine(XOFFSET - 4, YOFFSET, XOFFSET - 4, YOFFSET + CHEIGHT*B WIDTH + 6) GraphicsWindow.DrawLine(XOFFSET + CWIDTH*BWIDTH + 4, YOFFSET, XOFFSET + CWIDTH *BWIDTH + 4, YOFFSET + CHEIGHT*BWIDTH + 6) GraphicsWindow.DrawLine(XOFFSET - 4, YOFFSET + CHEIGHT*BWIDTH + 4, XOFFSET + C WIDTH*BWIDTH + 4, YOFFSET + CHEIGHT*BWIDTH + 4)

GraphicsWindow.PenColor = "Black" GraphicsWindow.BrushColor = "Pink" x = XOFFSET + PREVIEW_xpos * BWIDTH - BWIDTH y = YOFFSET + PREVIEW_ypos * BWIDTH - BWIDTH GraphicsWindow.FillRectangle(x, y, BWIDTH * 5, BWIDTH * 6) GraphicsWindow.DrawRectangle(x, y, BWIDTH * 5, BWIDTH * 6) GraphicsWindow.FillRectangle(x - 20, y + 190, 310, 170) GraphicsWindow.DrawRectangle(x - 20, y + 190, 310, 170) GraphicsWindow.BrushColor = "Black" GraphicsWindow.FontItalic = "False" GraphicsWindow.FontName = "Comic Sans MS" GraphicsWindow.FontSize = 16 GraphicsWindow.DrawText(x, y + 200, "Game control keys:") GraphicsWindow.DrawText(x + 25, y + 220, "Left Arrow = Move piece left") GraphicsWindow.DrawText(x + 25, y + 240, "Right Arrow = Move piece right") GraphicsWindow.DrawText(x + 25, y + 260, "Up Arrow = Rotate piece") GraphicsWindow.DrawText(x + 25, y + 280, "Down Arrow = Drop piece") GraphicsWindow.DrawText(x, y + 320, "Press to stop game") Program.Delay(200) ' without this delay, the above text will use the fontsize of the score GraphicsWindow.BrushColor = "Black" GraphicsWindow.FontName = "Georgia" GraphicsWindow.FontItalic = "True" GraphicsWindow.FontSize = 36 GraphicsWindow.DrawText(x - 20, y + 400, "Small Basic Tetris") Program.Delay(200) ' without this delay, the above text will use the fontsize of the score GraphicsWindow.FontSize = 16 GraphicsWindow.DrawText(x - 20, y + 440, "ver.0.1") Program.Delay(200) ' without this delay, the above text will use the fontsize of the score score = 0 PrintScore() EndSub Sub PrintScore GraphicsWindow.PenWidth = 4 GraphicsWindow.BrushColor = "Pink" GraphicsWindow.FillRectangle(500, 65, 153, 50) GraphicsWindow.BrushColor = "Black" GraphicsWindow.DrawRectangle(500, 65, 153, 50) GraphicsWindow.FontItalic = "False" GraphicsWindow.FontSize = 32 GraphicsWindow.FontName = "Impact" GraphicsWindow.BrushColor = "Black" GraphicsWindow.DrawText(505, 70, Text.Append(Text.GetSubText( "00000000", 0, 8 - Text.GetLength( score ) ), score)) EndSub Sub ' ' ' SetupTemplates each piece has 4 boxes. the index of each entry within a piece represents the box number (1-4) the value of each entry represents to box zero-based box coordinate within t

he piece: tens place is x, ones place y '_X_ '_X_ '_XX Array.SetValue("template1", Array.SetValue("template1", Array.SetValue("template1", Array.SetValue("template1", Array.SetValue("template1", Array.SetValue("template1", Array.SetValue("template1", Array.SetValue("template1", '_X_ '_X_ 'XX_ Array.SetValue("template2", Array.SetValue("template2", Array.SetValue("template2", Array.SetValue("template2", Array.SetValue("template2", Array.SetValue("template2", Array.SetValue("template2", Array.SetValue("template2", '_X_ 'XXX '_ Array.SetValue("template3", Array.SetValue("template3", Array.SetValue("template3", Array.SetValue("template3", Array.SetValue("template3", Array.SetValue("template3", Array.SetValue("template3", Array.SetValue("template3", 'XX_ 'XX_ '_ Array.SetValue("template4", Array.SetValue("template4", Array.SetValue("template4", Array.SetValue("template4", Array.SetValue("template4", Array.SetValue("template4", Array.SetValue("template4", Array.SetValue("template4", 0, 10) 1, 11) 2, 12) 3, 22) "color", "Yellow") "dim", 3) "pviewx", -12) "pviewy", 12)

0, 10) 1, 11) 2, 12) 3, 02) "color", "Magenta") "dim", 3) "pviewx", 12) "pviewy", 12)

0, 10) 1, 01) 2, 11) 3, 21) "color", "Gray") "dim", 3) "pviewx", 0) "pviewy", 25)

0, 00) 1, 10) 2, 01) 3, 11) "color", "Cyan") "dim", 2) "pviewx", 12) "pviewy", 25)

'XX_ '_XX '_ Array.SetValue("template5", 0, 00) Array.SetValue("template5", 1, 10)

Array.SetValue("template5", Array.SetValue("template5", Array.SetValue("template5", Array.SetValue("template5", Array.SetValue("template5", Array.SetValue("template5", '_XX 'XX_ '_ Array.SetValue("template6", Array.SetValue("template6", Array.SetValue("template6", Array.SetValue("template6", Array.SetValue("template6", Array.SetValue("template6", Array.SetValue("template6", Array.SetValue("template6", '_X '_X '_X '_X Array.SetValue("template7", Array.SetValue("template7", Array.SetValue("template7", Array.SetValue("template7", Array.SetValue("template7", Array.SetValue("template7", Array.SetValue("template7", Array.SetValue("template7", EndSub

2, 11) 3, 21) "color", "Green") "dim", 3) "pviewx", 0) "pviewy", 25)

0, 10) 1, 20) 2, 01) 3, 11) "color", "Blue") "dim", 3) "pviewx", 0) "pviewy", 25)

0, 10) 1, 11) 2, 12) 3, 13) "color", "Red") "dim", 4) "pviewx", 0) "pviewy", 0)