Post Reply 
Micro$oft SMALLBASIC
08-15-2020, 03:34 PM
Post: #1
Micro$oft SMALLBASIC
Hi.

Important for teachers.

I am starting to use Micro$oft SMALLBASIC to teach algorithmic logic to beginning students.
SMALLBASIC has three independent windows

Two-way console or text input and output window
Graph window
Graph window by turtle interface

Two versions, one for desktop execution and one online

SB can detect various events for the mouse and keyboard, and even with external hardware like arduino and others.

SB https://smallbasic-publicwebsite.azurewebsites.net/

an example of Game written in SB
PHP Code:
GraphicsWindow.KeyDown HandleKey
GraphicsWindow
.BackgroundColor GraphicsWindow.GetColorFromRGB253252251 )

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 Heightin 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() ' 
intemplate reth
    nextPiece 
h
    DrawPreviewPiece
()

    
thisPiece

    ypos 
0
    done 
0
    xpos 
' always drop from column 3
    CheckStop() ' 
inyposxposh retdone
    
If done 1 Then
      ypos 
ypos 1
      MovePiece
()  'in: ypos, xpos, h
      end = 1
    EndIf

    yposdelta = 0
    While done = 0 Or yposdelta > 0
      MovePiece()  '
inyposxposh

      
' 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 freespinwhen 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()  ' 
inyposxposhmoveDirection retinvalidMove or -or if move is invalidotherwise 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()  '
inyposxposh
  
EndIf

  
' Move piece down
  If GraphicsWindow.LastKey = "Down" or GraphicsWindow.LastKey = "Space" Then
    delay = 0
  EndIf

  ' 
Rotate piece
  
If GraphicsWindow.LastKey "Z" Then
    basetemplate 
= Array.GetValue(h, -1)  ' Array.GetValue(h, -1) = the template name
    template = "temptemplate"
    rotation = "CW"
    CopyPiece()  '
in basetemplatetemplaterotation

    
Array.SetValue(h, -1template' Array.GetValue(h, -1) = the template name
    moveDirection = 0
    ValidateMove()  ' 
inyposxposhmoveDirection retinvalidMove or -or if move is invalidotherwise 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 only
      
' 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 name
        rotation 
"COPY"
        
CopyPiece()  'in basetemplate, template, rotation
        yposdelta = 1 ' 
Don't move down if we rotate
        MovePiece()  '
inyposxposh
      
ElseIf invalidMove 2 Then
        
' Don't support shifting piece when hitting another piece to the right or left.
        
xpos 99 ' exit the loop
      Else
        ' 
if the rotated piece can't be placed, move it left or right and try again.
        xpos = xpos - invalidMove
        ValidateMove()  ' 
inyposxposhmoveDirection retinvalidMove or -or if move is invalidotherwise 0
      
EndIf
    EndWhile

    If 
invalidMove <> 0 Then
      xpos 
xposbk
      
Array.SetValue(h, -1basetemplate' 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.GetValue(h, -1) = the template name
  YOFFSET 
YOFFSET + Array.GetValue(Array.GetValue(h, -1), "pviewy"' Array.GetValue(h, -1) = the template name
  MovePiece()  '
inyposxposh

  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' x
      v 
= Array.GetValue(basetemplatei)

      
'x = Math.Floor(v/10)
      '
Math.Remainder(v10)

      
' 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 0 to BOXES ' x' y y' = x
      v = Array.GetValue(basetemplate, i)
      '
Math.Floor(v/10)
      
'y = Math.Remainder(v, 10)

      ' 
new and y
      x 
= (Math.Remainder(v10))
      
Math.Floor(v/10)
      Array.
SetValue(templatei10 y)
    EndFor
  ElseIf 
rotation "COPY" Then
    
For 0 to BOXES 1
      
Array.SetValue(templatei, Array.GetValue(basetemplatei))
    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 ' 
intemplate reth
  
' Create a new handle, representing an arrayName, that will represent the piece
  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 
0 to BOXES 1
    s 
Shapes.AddRectangle(BWIDTHBWIDTH)
    
Shapes.Move(s, -BWIDTH, -BWIDTH' move off screen
    Array.SetValue(h, i, s)
  EndFor
EndSub

Sub MovePiece '
inyposxposhypos/xpos is 0-19representing the top/left box coordinate of the piece on the canvash returned by CreatePiece
  
For 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(hi) = 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, YOFFSET + ypos * BWIDTH + y * BWIDTH)
  EndFor
EndSub

Sub ValidateMove ' 
inyposxposhmoveDirection retinvalidMove or -or if move is invalidotherwise 0
  i 
0
  invalidMove 
0
  
While 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.
    
Math.Floor(v/10)
    
Math.Remainder(v10)

    If (
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", (xpos moveDirection) + (ypos) * CWIDTH) <> "." Then
      invalidMove 
2
      i 
BOXES ' force getting out of the loop
    EndIf

    i = i + 1
  EndWhile
EndSub


Sub CheckStop ' 
inyposxposh retdone
  done 
0
  i 
0
  
While 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.
    
Math.Floor(v/10)
    
Math.Remainder(v10)

    If 
ypos CHEIGHT Or Array.GetValue("c", (xpos) + (ypos) * CWIDTH) <> "." Then
      done 
1
      i 
BOXES ' force getting out of the loop
    EndIf

    i = i + 1
  EndWhile

  ' 
If we need to stop the piecemove the box handles to the canvas
  
If done 1 Then
    
For 0 to BOXES 1
      v 
= Array.GetValue(Array.GetValue(h, -1), i' Array.GetValue(h, -1) = the template name
      '
Math.Floor(v/10)
      
'y = Math.Remainder(v, 10)
      Array.SetValue("c", (Math.Floor(v/10) + xpos) + (Math.Remainder(v, 10) + ypos - 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 rowstarting from the bottom
  
For 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."."), then remove the line.
      If 
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 CWIDTHpiece)
            
Shapes.Move(pieceShapes.GetLeft(piece), Shapes.GetTop(piece) + BWIDTH)
          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, GraphicsWindow.Width, GraphicsWindow.Height)


  GraphicsWindow.BrushColor = "LightYellow"
  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 BWIDTHYOFFSET BWIDTHBWIDTHBWIDTH)
    EndFor
  EndFor

  
GraphicsWindow.PenWidth 4
  GraphicsWindow
.PenColor "Black"
  
GraphicsWindow.DrawLine(XOFFSETYOFFSETXOFFSETYOFFSET CHEIGHT*BWIDTH)
  
GraphicsWindow.DrawLine(XOFFSET CWIDTH*BWIDTHYOFFSETXOFFSET CWIDTH*BWIDTHYOFFSET CHEIGHT*BWIDTH)
  
GraphicsWindow.DrawLine(XOFFSETYOFFSET CHEIGHT*BWIDTHXOFFSET CWIDTH*BWIDTHYOFFSET CHEIGHT*BWIDTH)

  
GraphicsWindow.PenColor "Lime"
  
GraphicsWindow.DrawLine(XOFFSET 4YOFFSETXOFFSET 4YOFFSET CHEIGHT*BWIDTH 6)
  
GraphicsWindow.DrawLine(XOFFSET CWIDTH*BWIDTH 4YOFFSETXOFFSET CWIDTH*BWIDTH 4YOFFSET CHEIGHT*BWIDTH 6)
  
GraphicsWindow.DrawLine(XOFFSET 4YOFFSET CHEIGHT*BWIDTH 4XOFFSET CWIDTH*BWIDTH 4YOFFSET CHEIGHT*BWIDTH 4)

  
GraphicsWindow.PenColor "Black"
  
GraphicsWindow.BrushColor "Pink"
  
XOFFSET PREVIEW_xpos BWIDTH BWIDTH
  y 
YOFFSET PREVIEW_ypos BWIDTH BWIDTH
  GraphicsWindow
.FillRectangle(xyBWIDTH 5BWIDTH 6)
  
GraphicsWindow.DrawRectangle(xyBWIDTH 5BWIDTH 6)

  
GraphicsWindow.FillRectangle(20190310170)
  
GraphicsWindow.DrawRectangle(20190310170)

  
GraphicsWindow.BrushColor "Black"
  
GraphicsWindow.FontItalic "False"
  
GraphicsWindow.FontName "Comic Sans MS"
  
GraphicsWindow.FontSize 16
  GraphicsWindow
.DrawText(x200"Game control keys:")
  
GraphicsWindow.DrawText(25220"Left Arrow = Move piece left")
  
GraphicsWindow.DrawText(25240"Right Arrow = Move piece right")
  
GraphicsWindow.DrawText(25260"Up Arrow = Rotate piece")
  
GraphicsWindow.DrawText(25280"Down Arrow = Drop piece")
  
GraphicsWindow.DrawText(x320"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 delaythe above text will use the fontsize of the score
  GraphicsWindow
.FontSize 16
  GraphicsWindow
.DrawText(20440"ver.0.1")
  
GraphicsWindow.DrawText(20460"http://www.smallbasic.com")

  
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 the piecetens place is xones place y

  
'_X_
  '
_X_
  
'_XX

  Array.SetValue("template1", 0, 10)
  Array.SetValue("template1", 1, 11)
  Array.SetValue("template1", 2, 12)
  Array.SetValue("template1", 3, 22)
  Array.SetValue("template1", "color", "Yellow")
  Array.SetValue("template1", "dim", 3)
  Array.SetValue("template1", "pviewx", -12)
  Array.SetValue("template1", "pviewy", 12)


  '
_X_
  
'_X_
  '
XX_
  
Array.SetValue("template2"010)
  Array.
SetValue("template2"111)
  Array.
SetValue("template2"212)
  Array.
SetValue("template2"302)
  Array.
SetValue("template2""color""Magenta")
  Array.
SetValue("template2""dim"3)
  Array.
SetValue("template2""pviewx"12)
  Array.
SetValue("template2""pviewy"12)


  
'_X_
  '
XXX
  
'_
  Array.SetValue("template3", 0, 10)
  Array.SetValue("template3", 1, 01)
  Array.SetValue("template3", 2, 11)
  Array.SetValue("template3", 3, 21)
  Array.SetValue("template3", "color", "Gray")
  Array.SetValue("template3", "dim", 3)
  Array.SetValue("template3", "pviewx", 0)
  Array.SetValue("template3", "pviewy", 25)


  '
XX_
  
'XX_
  '
_
  
Array.SetValue("template4"000)
  Array.
SetValue("template4"110)
  Array.
SetValue("template4"201)
  Array.
SetValue("template4"311)
  Array.
SetValue("template4""color""Cyan")
  Array.
SetValue("template4""dim"2)
  Array.
SetValue("template4""pviewx"12)
  Array.
SetValue("template4""pviewy"25)


  
'XX_
  '
_XX
  
'_
  Array.SetValue("template5", 0, 00)
  Array.SetValue("template5", 1, 10)
  Array.SetValue("template5", 2, 11)
  Array.SetValue("template5", 3, 21)
  Array.SetValue("template5", "color", "Green")
  Array.SetValue("template5", "dim", 3)
  Array.SetValue("template5", "pviewx", 0)
  Array.SetValue("template5", "pviewy", 25)


  '
_XX
  
'XX_
  '
_
  
Array.SetValue("template6"010)
  Array.
SetValue("template6"120)
  Array.
SetValue("template6"201)
  Array.
SetValue("template6"311)
  Array.
SetValue("template6""color""Blue")
  Array.
SetValue("template6""dim"3)
  Array.
SetValue("template6""pviewx"0)
  Array.
SetValue("template6""pviewy"25)


  
'_X
  '
_X
  
'_X
  '
_X
  
Array.SetValue("template7"010)
  Array.
SetValue("template7"111)
  Array.
SetValue("template7"212)
  Array.
SetValue("template7"313)
  Array.
SetValue("template7""color""Red")
  Array.
SetValue("template7""dim"4)
  Array.
SetValue("template7""pviewx"0)
  Array.
SetValue("template7""pviewy"0)
EndSub 

[Image: tetris.png]
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
Micro$oft SMALLBASIC - compsystems - 08-15-2020 03:34 PM
RE: Micro$oft SMALLBASIC - compsystems - 08-16-2020, 03:36 PM



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