Microsoft Small Basic

Program Listing: JPH449-2
' Frustration 0.4b
' Small Basic version written by Nonki Takahashi.
'
' History:
' 0.4b 2014-06-17 Supported ReturnPiece. (JPH449-2)
' 0.3a 2014-06-16 Enabled player's UI. (JPH449-1)
' 0.2a 2014-06-11 Added demo but still alpha. (JPH449-0)
' 0.1a 2014-06-09 Created as alpha version. (JPH449)
'
' TODO [✔] return opponent piece at the same point
' TODO [ ] select a piece to move from 4
' TODO [✔] enable player's UI
' TODO [ ] show score
'
GraphicsWindow.Title = "Frustration 0.4b"
Not = "False=True;True=False;"
gw = 598
gh = 428
GraphicsWindow.Width = gw
GraphicsWindow.Height = gh
DrawBoard()
'DumpBoard()
turn = 4
path[1]="1=1;2=2;3=3;4=4;5=5;6=6;7=7;8=8;9=9;10=10;11=11;12=20;13=21;14=22;15=23;16=24;17=25;18=26;19=35;20=36;21=37;22=38;23=39;24=40;25=41;26=50;27=51;28=52;29=53;30=54;31=55;32=56;33=12;34=13;35=14;36=15;"
path[2]="1=16;2=17;3=18;4=19;5=20;6=21;7=22;8=23;9=24;10=25;11=26;12=35;13=36;14=37;15=38;16=39;17=40;18=41;19=50;20=51;21=52;22=53;23=54;24=55;25=56;26=5;27=6;28=7;29=8;30=9;31=10;32=11;33=27;34=28;35=29;36=30;"
path[3]="1=31;2=32;3=33;4=34;5=35;6=36;7=37;8=38;9=39;10=40;11=41;12=50;13=51;14=52;15=53;16=54;17=55;18=56;19=5;20=6;21=7;22=8;23=9;24=10;25=11;26=20;27=21;28=22;29=23;30=24;31=25;32=26;33=42;34=43;35=44;36=45;"
path[4]="1=46;2=47;3=48;4=49;5=50;6=51;7=52;8=53;9=54;10=55;11=56;12=5;13=6;14=7;15=8;16=9;17=10;18=11;19=20;20=21;21=22;22=23;23=24;24=25;25=26;26=35;27=36;28=37;29=38;30=39;31=40;32=41;33=57;34=58;35=59;36=60;"
url = "http://www.nonkit.com/smallbasic.files/"
winner = 0
goal = "1=False;2=False;3=False;4=False;"
i = 1
While winner < 3
lastTurn = turn
turn = Math.Remainder(i - 1, 4) + 1
Shapes.HideShape(turnObj[lastTurn])
Shapes.ShowShape(turnObj[turn])
If Not[goal[turn]] Then
If turn = 3 Then ' Human Player
clicked = "False"
error = "False"
GraphicsWindow.MouseDown = OnMouseDown
While Not[clicked]
If error Then
Sound.PlayAndWait(url + "boo.wav")
error = "False"
Else
Program.Delay(200)
EndIf
EndWhile
GraphicsWindow.MouseDown = DoNothing
EndIf
For j = 1 To 3
n = Math.GetRandomNumber(6)
Shapes.SetText(dice, n)
Sound.PlayClickAndWait()
Program.Delay(j * 100)
EndFor
MovePiece()
If pHit <> "" Then
ReturnPiece()
EndIf
Program.Delay(1000)
EndIf
i = i + 1
EndWhile
Sub DoNothing
EndSub
Sub DrawBoard
color = "1=ForestGreen;2=Gold;3=MediumBlue;4=Crimson;"
init = "1=g;2=y;3=b;4=r;"
GraphicsWindow.BrushColor = "LightGray"
rBoard = 190
x = gw / 2 - rBoard
y = gh / 2 - rBoard
GraphicsWindow.FillEllipse(x, y, rBoard * 2, rBoard * 2)
x0 = gw / 2
y0 = gh / 2
For i = 1 To 4
GraphicsWindow.PenWidth = 40
GraphicsWindow.PenColor = color[i]
param["a1"] = (2 + i) * 90 - 45
param["a2"] = (2 + i) * 90 + 45
param["x"] = x0
param["y"] = y0
param["r"] = rBoard * 0.75
param["da"] = 5
Draw_DrawArc()
sin = Math.Sin((i - 1) * Math.Pi / 2)
cos = Math.Cos((i - 1) * Math.Pi / 2)
x1 = x0 + rBoard * 0.7 * sin
y1 = y0 - rBoard * 0.7 * cos
GraphicsWindow.DrawLine(x0, y0, x1, y1)
EndFor
For i = 1 To 4
DrawQuarter()
EndFor
GraphicsWindow.PenWidth = 5
GraphicsWindow.PenColor = "LightGray"
GraphicsWindow.BrushColor = "Black"
param="x="+ (x0 - 40) + ";y="+ (y0 - 40) +";width=80;height=80;border-radius=20;"
Draw_FillRoundRectangle()
Draw_DrawRoundRectangle()
param="x="+ (x0 - 20) + ";y="+ (y0 - 20) +";width=40;height=40;border-radius=10;"
GraphicsWindow.BrushColor = "White"
Draw_FillRoundRectangle()
GraphicsWindow.BrushColor = "Black"
GraphicsWindow.FontName = "Courier New"
GraphicsWindow.FontSize = 20
dice = Shapes.AddText(1)
Shapes.Move(dice, x0 - 6, y0 - 10)
GraphicsWindow.BrushColor = "White"
GraphicsWindow.PenWidth = 0
dome = Shapes.AddEllipse(70, 70)
Shapes.SetOpacity(dome, 20)
Shapes.Move(dome, x0 - 35, y0 - 35)
GraphicsWindow.BrushColor = "Gray"
GraphicsWindow.FontName = "Arial"
GraphicsWindow.DrawText(10, 10, "TURN")
For i = 1 To 4
GraphicsWindow.BrushColor = color[i]
turnObj[i] = Shapes.AddEllipse(rPiece * 2, rPiece * 2)
Shapes.Move(turnObj[i], 70, 10)
Shapes.HideShape(turnObj[i])
EndFor
EndSub
Sub DrawQuarter
' param i
' create piece 1-4
sin = Math.Sin((i - 1) * Math.Pi / 2)
cos = Math.Cos((i - 1) * Math.Pi / 2)
rPiece = 10
x = x0 + (rBoard - rPiece * 1.7) * sin
y = y0 - (rBoard - rPiece * 1.7) * cos
GraphicsWindow.BrushColor = color[i]
GraphicsWindow.PenWidth = 0
For j = 1 To 4
xj = x + (j - 2.5) * rPiece * 2.2 * cos - rPiece
yj = y + (j - 2.5) * rPiece * 2.2 * sin - rPiece
piece[init[i] + j]["obj"] = Shapes.AddEllipse(rPiece * 2, rPiece * 2)
Shapes.Move(piece[init[i] + j]["obj"], xj, yj)
board[j + (i - 1) * 15]["piece"] = init[i] + j
piece[init[i] + j]["pos"] = j
EndFor
' draw start 1-4
GraphicsWindow.BrushColor = "#80FFFFFF"
GraphicsWindow.PenWidth = 2
GraphicsWindow.PenColor = "LightGray"
For j = 1 To 4
xj = x + (j - 2.5) * rPiece * 2.2 * cos - rPiece
yj = y + (j - 2.5) * rPiece * 2.2 * sin - rPiece
GraphicsWindow.FillEllipse(xj, yj, rPiece * 2, rPiece * 2)
GraphicsWindow.DrawEllipse(xj, yj, rPiece * 2, rPiece * 2)
board[j + (i - 1) * 15]["x"] = xj
board[j + (i - 1) * 15]["y"] = yj
EndFor
' draw path 5-11
For j = 1 To 7
sinj = Math.Sin((i - 1 + (j - 0.5) / 7) * Math.Pi / 2)
cosj = Math.Cos((i - 1 + (j - 0.5) / 7) * Math.Pi / 2)
xj = x0 + (rBoard * 0.75 * sinj) - rPiece
yj = y0 - (rBoard * 0.75 * cosj) - rPiece
If j = 1 Then
GraphicsWindow.BrushColor = "Black"
Else
GraphicsWindow.BrushColor = "#80FFFFFF"
EndIf
GraphicsWindow.FillEllipse(xj, yj, rPiece * 2, rPiece * 2)
GraphicsWindow.DrawEllipse(xj, yj, rPiece * 2, rPiece * 2)
board[j + 4 + (i - 1) * 15]["x"] = xj
board[j + 4 + (i - 1) * 15]["y"] = yj
EndFor
' draw goal 12-15
GraphicsWindow.BrushColor = "Black"
For j = 1 To 4
xj = x0 + (rBoard * (0.18 + j / 4 * 0.46) * sin) - rPiece
yj = y0 - (rBoard * (0.18 + j / 4 * 0.46) * cos) - rPiece
GraphicsWindow.FillEllipse(xj, yj, rPiece * 2, rPiece * 2)
GraphicsWindow.DrawEllipse(xj, yj, rPiece * 2, rPiece * 2)
board[(5 - j) + 11 + (i - 1) * 15]["x"] = xj
board[(5 - j) + 11 + (i - 1) * 15]["y"] = yj
EndFor
EndSub
Sub DumpBoard
n = Array.GetItemCount(board)
For i = 1 To n
GraphicsWindow.DrawText(board[i]["x"], board[i]["y"], i)
EndFor
EndSub
Sub MovePiece
' param turn
' param n - cast of dice
' return pHit - piece to be returned
pos = piece[init[turn] + 4]["pos"]
pHit = ""
If pos = 4 Then
If n = 6 Then
board[path[turn][pos]]["piece"] = ""
x = board[path[turn][pos + 1]]["x"]
y = board[path[turn][pos + 1]]["y"]
Shapes.Animate(piece[init[turn] + 4]["obj"], x, y, 500)
piece[init[turn] + 4]["pos"] = pos + 1
Program.Delay(500)
Sound.PlayClick()
pHit = board[path[turn][pos + 1]]["piece"]
board[path[turn][pos + 1]]["piece"] = init[turn] + 4
EndIf
ElseIf pos + n <= 36 Then
If Text.StartsWith(board[path[turn][pos + n]]["piece"], init[turn]) Then
' same color
Sound.Play(url + "boo.wav")
Else
board[path[turn][pos]]["piece"] = ""
For j = 1 To n
x = board[path[turn][pos + j]]["x"]
y = board[path[turn][pos + j]]["y"]
Shapes.Animate(piece[init[turn] + 4]["obj"], x, y, 500)
Program.Delay(500)
Sound.PlayClick()
EndFor
piece[init[turn] + 4]["pos"] = pos + n
If pos + n = 36 Then
Sound.PlayAndWait(url + "tada.wav")
winner = winner + 1
goal[turn] = "True"
EndIf
pHit = board[path[turn][pos + n]]["piece"]
board[path[turn][pos + n]]["piece"] = init[turn] + 4
EndIf
EndIf
EndSub
Sub OnMouseDown
mx = GraphicsWindow.MouseX
my = GraphicsWindow.MouseY
d = Math.SquareRoot(Math.Power((mx - x0), 2) + Math.Power((my - y0), 2))
If d <= 35 Then
clicked = "True"
Else
error = "True"
EndIf
EndSub
Sub ReturnPiece
' param pHit - piece to be returned
Sound.PlayAndWait(url + "boo.wav")
For tHit = 1 To 4
If Text.StartsWith(pHit, init[tHit]) Then
Goto rpBreak
EndIf
EndFor
rpBreak:
x = board[path[tHit][4]]["x"]
y = board[path[tHit][4]]["y"]
Shapes.Animate(piece[init[tHit] + 4]["obj"], x, y, 1500)
Program.Delay(1500)
Sound.PlayClick()
board[path[tHit][4]]["piece"] = pHit
piece[pHit]["pos"] = 4
EndSub
Sub Draw_DrawArc
' param x, y - center of arc
' param r - radius of arc
' param a1, a2 - start and end angle
Stack.PushValue("local", param)
Stack.PushValue("local", local)
Stack.PushValue("local", a)
local = param
param = ""
local["pw"] = GraphicsWindow.PenWidth
local["pc"] = GraphicsWindow.PenColor
local["bc"] = GraphicsWindow.BrushColor
GraphicsWindow.BrushColor = local["pc"]
GraphicsWindow.PenWidth = 1
local["r1"] = local["r"] - local["pw"] / 2
local["r2"] = local["r"] + local["pw"] / 2
For a = local["a1"] To local["a2"] Step local["da"]
local["rad"] = Math.GetRadians(a)
param["x1"] = local["x"] + local["r1"] * Math.Cos(local["rad"])
param["y1"] = local["y"] + local["r1"] * Math.Sin(local["rad"])
param["x2"] = local["x"] + local["r2"] * Math.Cos(local["rad"])
param["y2"] = local["y"] + local["r2"] * Math.Sin(local["rad"])
If local["a1"] < a Then
Draw_FillQuadrangle()
EndIf
param["x4"] = param["x1"]
param["y4"] = param["y1"]
param["x3"] = param["x2"]
param["y3"] = param["y2"]
EndFor
GraphicsWindow.BrushColor = local["bc"]
GraphicsWindow.PenWidth = local["pw"]
a = Stack.PopValue("local")
local = Stack.PopValue("local")
param = Stack.PopValue("local")
EndSub
Sub Draw_DrawRoundRectangle
Stack.PushValue("local", param)
Stack.PushValue("local", local)
local = param
param = ""
param["r"] = local["border-radius"]
If (local["width"] / 2 < param["r"]) Or (local["height"] / 2 < param["r"]) Then
param["r"] = Math.Min(local["width"] / 2, local["height"] / 2)
EndIf
param["da"] = 5
param["x"] = local["x"] + param["r"]
param["y"] = local["y"] + param["r"]
param["a1"] = 180
param["a2"] = 270
Draw_DrawArc()
GraphicsWindow.DrawLine(local["x"] + param["r"], local["y"], local["x"] + local["width"] - param["r"], local["y"])
param["x"] = local["x"] + local["width"] - param["r"]
param["y"] = local["y"] + param["r"]
param["a1"] = 270
param["a2"] = 360
Draw_DrawArc()
GraphicsWindow.DrawLine(local["x"] + local["width"], local["y"] + param["r"], local["x"] + local["width"], local["y"] + local["height"] - param["r"])
param["x"] = local["x"] + local["width"] - param["r"]
param["y"] = local["y"] + local["height"] - param["r"]
param["a1"] = 0
param["a2"] = 90
Draw_DrawArc()
GraphicsWindow.DrawLine(local["x"] + param["r"], local["y"] + local["height"], local["x"] + local["width"] - param["r"], local["y"] + local["height"])
param["x"] = local["x"] + param["r"]
param["y"] = local["y"] + local["height"] - param["r"]
param["a1"] = 90
param["a2"] = 180
Draw_DrawArc()
GraphicsWindow.DrawLine(local["x"], local["y"] + param["r"], local["x"], local["y"] + local["height"] - param["r"])
local = Stack.PopValue("local")
param = Stack.PopValue("local")
EndSub
Sub Draw_FillRoundRectangle
Stack.PushValue("local", param)
If (param["width"] / 2 < param["border-radius"]) Or (param["height"] / 2 < param["border-radius"]) Then
param["border-radius"] = Math.Min(param["width"] / 2, param["height"] / 2)
EndIf
GraphicsWindow.FillEllipse(param["x"], param["y"], param["border-radius"] * 2, param["border-radius"] * 2)
GraphicsWindow.FillRectangle(param["x"] + param["border-radius"], param["y"], param["width"] - param["border-radius"] * 2, param["height"])
GraphicsWindow.FillEllipse(param["x"] + param["width"] - param["border-radius"] * 2, param["y"], param["border-radius"] * 2, param["border-radius"] * 2)
GraphicsWindow.FillRectangle(param["x"], param["y"] + param["border-radius"], param["width"], param["height"] - param["border-radius"] * 2)
GraphicsWindow.FillEllipse(param["x"], param["y"] + param["height"] - param["border-radius"] * 2, param["border-radius"] * 2, param["border-radius"] * 2)
GraphicsWindow.FillEllipse(param["x"] + param["width"] - param["border-radius"] * 2, param["y"] + param["height"] - param["border-radius"] * 2, param["border-radius"] * 2, param["border-radius"] * 2)
param = Stack.PopValue("local")
EndSub
Sub Draw_FillQuadrangle
' param x1, y1, x2, y2, x3, y3, x4, y4 - edges
GraphicsWindow.FillTriangle(param["x1"], param["y1"], param["x2"], param["y2"], param["x3"], param["y3"])
GraphicsWindow.FillTriangle(param["x3"], param["y3"], param["x4"], param["y4"], param["x1"], param["y1"])
GraphicsWindow.DrawLine(param["x1"], param["y1"], param["x3"], param["y3"])
GraphicsWindow.DrawLine(param["x1"], param["y1"], param["x4"], param["y4"])
GraphicsWindow.DrawLine(param["x2"], param["y2"], param["x3"], param["y3"])
GraphicsWindow.DrawLine(param["x3"], param["y3"], param["x4"], param["y4"])
EndSub