Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ' This program is written for Monkey
- ' It's designed to be exported for HTML5
- '''''''''''''''''''''''''''''''''''''''''''
- '' -- Triangle Solver 1.2 -- ''
- '' by Brandon DeRosier ''
- '''''''''''''''''''''''''''''''''''''''''''
- '' Feel free to modify and redistribute! ''
- '''''''''''''''''''''''''''''''''''''''''''
- '' Change Log! ''
- ''---------------------------------------''
- '' v1.2: ''
- '' - Area now solved using numerically ''
- '' stable version of Heron's formula. ''
- '' (Thanks mathwanker of Reddit!) ''
- '' - Formulas used to solve missing ''
- '' sides and angles are now displayed. ''
- '' (Thanks ninjarob of Reddit!) ''
- '' - Input validation for angles added. ''
- '' (Thanks azadder of Reddit!) ''
- '' - Sound is disabled by default. ''
- '' v1.1: ''
- '' - Calculates the area of solved ''
- '' triangles. ''
- '' - Support for radians implemented. ''
- '' - Fixed some rounding bugs. ''
- '' - Made UI a little easier. (Mouse ''
- '' selection, backspace/delete works) ''
- '' - Added sounds. ''
- '''''''''''''''''''''''''''''''''''''''''''
- Strict
- Import mojo.app
- Import mojo.graphics
- Import mojo.input
- Import mojo.audio
- Class Vector3
- Field a:Float, b:Float, c:Float
- Method New(_a:Float = 0, _b:Float = 0, _c:Float = 0)
- a = _a
- b = _b
- c = _c
- End
- Method propagate:Void(variable:String)
- If variable = "a"
- b = a
- c = a
- Else If variable = "b"
- a = b
- c = b
- Else If variable = "c"
- a = c
- b = c
- End
- End
- End
- Class Triangle
- Field angles:Vector3, sides:Vector3
- Method New(angleA:Float = 0, angleB:Float = 0, angleC:Float = 0, sideA:Float = 0, sideB:Float = 0, sideC:Float = 0)
- While (angleA >= 180)
- angleA -= 180
- End
- While (angleB >= 180)
- angleB -= 180
- End
- While (angleC >= 180)
- angleC -= 180
- End
- angles = New Vector3(angleA, angleB, angleC)
- sides = New Vector3(sideA, sideB, sideC)
- End
- Method PrintValues:Void()
- Print("Angle A: " + String(angles.a))
- Print("Angle B: " + String(angles.b))
- Print("Angle C: " + String(angles.c))
- Print("Side A: " + String(sides.a))
- Print("Side B: " + String(sides.b))
- Print("Side C: " + String(sides.c))
- End
- End
- Class TextObject
- Field x:Int, y:Int
- Field text:String
- Method New(_text:String, _x:Int, _y:Int)
- text = _text
- x = _x
- y = _y
- End
- Method Render:Void()
- DrawText text, x, y
- End
- End
- Class TriangleMath
- ' Basement functionality
- Method LoC:Float(angleA:Float, sideB:Float, sideC:Float) ' Law of Cosines - Solve for side
- Return Sqrt(Pow(sideB, 2) + Pow(sideC, 2) - 2.0*sideB*sideC*Cos(angleA))
- End
- Method iLoC:Float(sideA:Float, sideB:Float, sideC:Float) ' Inverse Law of Cosines - Solve for angle
- Return ACos((Pow(sideB, 2) + Pow(sideC, 2) - Pow(sideA, 2)) / (2.0*sideB*sideC))
- End
- Method LoS:Float(angleA:Float, angleB:Float, sideB:Float) ' Law of Sines - Solve for side
- Return Sin(angleA)*(sideB/Sin(angleB))
- End
- Method iLoS:Float(angleB:Float, sideA:Float, sideB:Float) ' Inverse Law of Sines - Solve for angle
- Return ASin(sideA/(sideB/Sin(angleB)))
- End
- Method TST:Float(angleB:Float, angleC:Float) ' Triangle Sum Theory - Solve for angle
- Local angleA:Float = 180.0 - (angleB + angleC)
- If (angleA < 0)
- Return 0
- End
- Return angleA
- End
- Method HF:Float(sideA:Float, sideB:Float, sideC:Float) ' Heron's Formula - Solve for area
- Return Sqrt((sideA + (sideB + sideC))*(sideC - (sideA - sideB))*(sideC + (sideA - sideB))*(sideA + (sideB - sideC)))/4.0
- End
- ' Lobby functionality
- Method SSS:Triangle(sideA:Float, sideB:Float, sideC:Float) ' Side-Side-Side
- Local angleA:Float = iLoC(sideA, sideB, sideC)
- Local angleB:Float = iLoC(sideB, sideA, sideC)
- Local angleC:Float = TST(angleA, angleB)
- Local result:Triangle = New Triangle(angleA, angleB, angleC, sideA, sideB, sideC)
- Return result
- End
- Method SAS:Triangle(sideC:Float, angleA:Float, sideB:Float, variation:Int = 0) ' Side-Angle-Side - Three variations: 0-sCaAsB, 1-sAaBsC, 2-sBaCsA
- Local sideA:Float = LoC(angleA, sideB, sideC)
- Local angleB:Float = iLoC(sideB, sideA, sideC)
- Local angleC:Float = TST(angleA, angleB)
- Local result:Triangle
- If (variation = 1) ' Inputs assumed to be sAaBsC
- result = New Triangle(angleC, angleA, angleB, sideC, sideA, sideB)
- Else If (variation = 2) ' Inputs assumed to be sBaCsA
- result = New Triangle(angleB, angleC, angleA, sideB, sideC, sideA)
- Else ' Inputs assumed to be sCaAsB
- result = New Triangle(angleA, angleB, angleC, sideA, sideB, sideC)
- End
- Return result
- End
- Method ASA:Triangle(angleB:Float, sideC:Float, angleA:Float, variation:Int = 0) ' Angle-Side-Angle - Three variations: 0-aBsCaA, 1-aCsAaB, 2-aAsBaC
- Local angleC:Float = TST(angleA, angleB)
- Local sideB:Float = LoS(angleB, angleC, sideC)
- Local sideA:Float = LoC(angleA, sideB, sideC)
- Local result:Triangle
- If (variation = 1) ' Inputs assumed to be aBsCaA
- result = New Triangle(angleC, angleA, angleB, sideC, sideA, sideB)
- Else If (variation = 2) ' Inputs assumed to be aCsAaB
- result = New Triangle(angleB, angleC, angleA, sideB, sideC, sideA)
- Else ' Inputs assumed to be aAsBaC
- result = New Triangle(angleA, angleB, angleC, sideA, sideB, sideC)
- End
- Return result
- End
- End
- Class Widget Abstract
- Field x:Float, y:Float, width:Float, height:Float
- Method New(_x:Float, _y:Float, _width:Float, _height:Float)
- x = _x
- y = _y
- width = _width
- height = _height
- End
- Method Update:Void() Abstract
- Method Render:Void() Abstract
- End
- Class LabelInput Extends Widget
- Field label:String, input:String
- Field labelColor:Vector3
- Field keyCode:Int
- Field rollOver:Bool
- Method New(_x:Float = 0, _y:Float = 0, _label:String = "Input", _keyCode:Int = KEY_ESCAPE, _labelColor:Vector3 = New Vector3(255, 255, 255))
- Super.New(_x, _y, 0, 0)
- label = _label
- input = ""
- labelColor = _labelColor
- keyCode = _keyCode
- rollOver = False
- End
- Method Update:Void()
- If (widgetFocus = keyCode)
- Local character:Int = GetChar()
- If ((character >= 48 And character <= 57) Or character = 46)
- If (((character = 46 And Not input.Contains(".")) Or character <> 46) And input.Length < 14)
- ChannelSound(typeSound)
- input += String.FromChar(character)
- Else
- ChannelSound(selectSound)
- End
- Else If (character = CHAR_BACKSPACE Or character = CHAR_DELETE)
- If (input.Length > 0)
- input = input[0..input.Length-1]
- ChannelSound(typeSound)
- Else
- ChannelSound(selectSound)
- End
- End
- If (KeyHit(KEY_R))
- ChannelSound(typeSound)
- input = ""
- End
- End
- If (MouseY() > y - 3 And MouseY() < y + 15)
- rollOver = True
- If (MouseHit(MOUSE_LEFT))
- ChannelSound(selectSound)
- widgetFocus = keyCode
- End
- Else
- rollOver = False
- End
- If (KeyHit(keyCode))
- ChannelSound(selectSound)
- widgetFocus = keyCode
- End
- End
- Method Render:Void()
- If (widgetFocus = keyCode)
- SetColor 255, 0, 0
- DrawCircle(x - 5, y + 5, 5)
- Else If (rollOver)
- SetColor 0, 255, 0
- DrawCircle(x - 5, y + 5, 5)
- End
- If (input = "" And widgetFocus <> keyCode)
- DrawText(label + " = Undefined", x, y)
- Else
- DrawText(label + " = " + input, x, y)
- End
- End
- End
- Global solution:Int = 0
- Global widgetFocus:Int
- Global typeSound:Sound, selectSound:Sound, backSound:Sound
- Global soundChannel:Int = 0
- Global playSound:Bool
- Function ChannelSound:Void(snd:Sound)
- If (playSound)
- If (soundChannel < 10)
- soundChannel += 1
- Else
- soundChannel = 0
- End
- StopChannel(soundChannel)
- PlaySound(snd)
- End
- End
- Class KegSolver Extends App
- Field tMath:TriangleMath
- Field solved:Triangle, solvedArea:Float
- Field inputs:LabelInput[6]
- Field solutionInfo:TextObject[7]
- Field mode:Int
- Method OnCreate:Void()
- SetUpdateRate 60
- tMath = New TriangleMath()
- solved = New Triangle(0, 0, 0, 0, 0, 0)
- typeSound = LoadSound("type.wav")
- selectSound = LoadSound("tick.wav")
- inputs[0] = New LabelInput(50, 50, "A) Angle A", KEY_A)
- inputs[1] = New LabelInput(50, 70, "S) Angle B", KEY_S)
- inputs[2] = New LabelInput(50, 90, "D) Angle C", KEY_D)
- inputs[3] = New LabelInput(50, 130, "Z) Side A", KEY_Z)
- inputs[4] = New LabelInput(50, 150, "X) Side B", KEY_X)
- inputs[5] = New LabelInput(50, 170, "C) Side C", KEY_C)
- For Local i:Int = 0 To 6
- Local j:Int = 0
- If (i >= 3 And i < 6)
- j = 20
- Else If (i >= 6)
- j = 40
- End
- solutionInfo[i] = New TextObject("Given", DeviceWidth() - 370, (i*20) + 260 + j)
- End
- mode = 0
- playSound = False
- End
- Method OnUpdate:Void()
- For Local input:LabelInput = Eachin inputs
- input.Update()
- End
- If (KeyHit(KEY_ENTER))
- ChannelSound(selectSound)
- Local fInputs:Float[6]
- For Local i:Int = 0 To 5
- If (inputs[i].input = "")
- fInputs[i] = 0
- Else
- Local inputValue:Float = Float(inputs[i].input)
- If (i < 3)
- fInputs[i] = convertInput(inputValue)
- Else
- fInputs[i] = inputValue
- End
- End
- Next
- Local unsolved:Triangle = New Triangle(fInputs[0], fInputs[1], fInputs[2], fInputs[3], fInputs[4], fInputs[5])
- solved = Solve(unsolved)
- If (solution > 1)
- solvedArea = tMath.HF(solved.sides.a, solved.sides.b, solved.sides.c)
- solutionInfo[6].text = "Sqrt((a+(b+c))*(c-(a-b))*(c+(a-b))*(a+(b-c)))/4"
- End
- End
- If (KeyHit(KEY_M))
- ChannelSound(selectSound)
- If (mode = 0)
- mode = 1
- inputs[0].input = floatToString(toRadians(Float(inputs[0].input)))
- inputs[1].input = floatToString(toRadians(Float(inputs[1].input)))
- inputs[2].input = floatToString(toRadians(Float(inputs[2].input)))
- Else
- mode = 0
- inputs[0].input = floatToString(toDegrees(Float(inputs[0].input)))
- inputs[1].input = floatToString(toDegrees(Float(inputs[1].input)))
- inputs[2].input = floatToString(toDegrees(Float(inputs[2].input)))
- End
- End
- If (KeyHit(KEY_T))
- If (playSound)
- playSound = False
- Else
- playSound = True
- ChannelSound(selectSound)
- End
- End
- End
- Method OnRender:Void()
- Cls 0, 0, 0
- For Local input:LabelInput = Eachin inputs
- input.Render()
- End
- DrawText "Input three values and press Enter (press R to reset a field):", 50, 20
- Local modeText:String
- If (mode = 0)
- modeText = "Degrees"
- Else If (mode = 1)
- modeText = "Radians"
- End
- DrawText "Angle units: " + modeText, DeviceWidth() - 320, DeviceHeight() - 30
- Local soundText:String
- If (playSound)
- soundText = "Enabled"
- Else
- soundText = "Disabled"
- End
- DrawText "Sound: " + soundText, DeviceWidth() - 140, DeviceHeight() - 30
- If (solution = 0)
- DrawText "Triangle Solver 1.2 by Brandon DeRosier, 2011.", 50, 230
- DrawText "Navigation:", 50, 260
- DrawText "- Press A, S, D, Z, X, or C to focus on corresponding angle/side inputs.", 60, 280
- DrawText "- Press R to reset the focused input field.", 60, 300
- DrawText "- Press M to toggle between degrees and radians for angle measurements.", 60, 320
- DrawText "- Press T to toggle sound.", 60, 340
- DrawText "- Press Enter to solve the triangle based on the inputs given.", 60, 360
- Else If (solution = 1)
- DrawText "Impossible to solve..", 50, 230
- DrawText "Guidelines:", 50, 260
- DrawText "- Three value inputs are needed.", 60, 280
- DrawText "- At least one of the inputs should be a side length.", 60, 300
- DrawText "- The sum of all angles must be less than 180 degrees (PI radians).", 60, 320
- Else If (solution > 1)
- If (solution = 2)
- DrawText "Solved using SSS (Side-Side-Side)", 50, 230
- Else If (solution = 3)
- DrawText "Solved using SAS (Side-Angle-Side) [First variation]", 50, 230
- Else If (solution = 4)
- DrawText "Solved using SAS (Side-Angle-Side) [Second variation]", 50, 230
- Else If (solution = 5)
- DrawText "Solved using SAS (Side-Angle-Side) [Third variation]", 50, 230
- Else If (solution = 6)
- DrawText "Solved using ASA (Angle-Side-Angle) [First variation]", 50, 230
- Else If (solution = 7)
- DrawText "Solved using ASA (Angle-Side-Angle) [Second variation]", 50, 230
- Else If (solution = 8)
- DrawText "Solved using ASA (Angle-Side-Angle) [Third variation]", 50, 230
- End
- DrawText "Angle A = " + convertValue(solved.angles.a), 50, 260
- DrawText "Angle B = " + convertValue(solved.angles.b), 50, 280
- DrawText "Angle C = " + convertValue(solved.angles.c), 50, 300
- DrawText "Side A = " + solved.sides.a, 50, 340
- DrawText "Side B = " + solved.sides.b, 50, 360
- DrawText "Side C = " + solved.sides.c, 50, 380
- DrawText "Area = " + solvedArea, 50, 420
- For Local info:TextObject = Eachin solutionInfo
- info.Render()
- End
- End
- End
- ' Attic functionality
- Method toRadians:Float(degrees:Float)
- If (String(degrees) = "NaN")
- degrees = 0
- End
- Return (degrees*PI)/180.0
- End
- Method toDegrees:Float(radians:Float)
- If (String(radians) = "NaN")
- radians = 0
- End
- Return (radians*180.0)/PI
- End
- Method convertValue:Float(number:Float)
- If (mode = 1)
- Return toRadians(number)
- End
- Return number
- End
- Method convertInput:Float(number:Float)
- If (mode = 1)
- Return toDegrees(number)
- End
- Return number
- End
- Method floatToString:String(number:Float)
- If (number = 0)
- Return ""
- End
- Return String(number)
- End
- Method Solve:Triangle(tri:Triangle)
- Local result:Triangle
- solution = 0
- For Local info:TextObject = Eachin solutionInfo
- info.text = "Given"
- End
- If (tri.angles.a > 0 And tri.angles.b > 0 And tri.angles.c = 0) ' Prerequisite - Solve last angle
- tri.angles.c = tMath.TST(tri.angles.a, tri.angles.b)
- solutionInfo[2].text = "TST: C = 180 - ( A + B )"
- Else If (tri.angles.c > 0 And tri.angles.a > 0 And tri.angles.b = 0)
- tri.angles.b = tMath.TST(tri.angles.a, tri.angles.c)
- solutionInfo[1].text = "TST: B = 180 - ( A + C )"
- Else If (tri.angles.b > 0 And tri.angles.c > 0 And tri.angles.a = 0)
- tri.angles.a = tMath.TST(tri.angles.b, tri.angles.c)
- solutionInfo[0].text = "TST: A = 180 - ( B + C )"
- End
- If (tri.sides.a > 0 And tri.sides.b > 0 And tri.sides.c > 0) ' SSS
- result = tMath.SSS(tri.sides.a, tri.sides.b, tri.sides.c)
- solutionInfo[0].text = "iLoC: A = ACos( ( b^2 + c^2 - a^2 ) / 2bc )"
- solutionInfo[1].text = "iLoC: B = ACos( ( a^2 + c^2 - b^2 ) / 2ac )"
- If (tri.angles.c = 0)
- solutionInfo[2].text = "TST: C = 180 - ( A + B )"
- End
- solution = 2
- Else If (tri.sides.c > 0 And tri.angles.a > 0 And tri.sides.b > 0) ' SAS original
- result = tMath.SAS(tri.sides.c, tri.angles.a, tri.sides.b, 0)
- solutionInfo[3].text = "LoC: a = Sqrt( b^2 + c^2 - 2bc*Cos( A ) )"
- solutionInfo[1].text = "iLoC: B = ACos( ( a^2 + c^2 - b^2 ) / 2ac )"
- If (tri.angles.c = 0)
- solutionInfo[2].text = "TST: C = 180 - ( A + B )"
- End
- solution = 3
- Else If (tri.sides.a > 0 And tri.angles.b > 0 And tri.sides.c > 0) ' SAS morph 1
- result = tMath.SAS(tri.sides.a, tri.angles.b, tri.sides.c, 1)
- solutionInfo[4].text = "LoC: b = Sqrt( a^2 + c^2 - 2ac*Cos( B ) )"
- solutionInfo[2].text = "iLoC: C = ACos( ( a^2 + b^2 - c^2 ) / 2ab )"
- If (tri.angles.a = 0)
- solutionInfo[0].text = "TST: A = 180 - ( B + C )"
- End
- solution = 4
- Else If (tri.sides.b > 0 And tri.angles.c > 0 And tri.sides.a > 0) ' SAS morph 2
- result = tMath.SAS(tri.sides.b, tri.angles.c, tri.sides.a, 2)
- solutionInfo[5].text = "LoC: c = Sqrt( a^2 + b^2 - 2ab*Cos( C ) )"
- solutionInfo[0].text = "iLoC: A = ACos( ( b^2 + c^2 - a^2 ) / 2bc )"
- If (tri.angles.b = 0)
- solutionInfo[1].text = "TST: B = 180 - ( A + C )"
- End
- solution = 5
- End
- If (solution = 0)
- If (tri.angles.b > 0 And tri.sides.c > 0 And tri.sides.b > 0 And tri.angles.c = 0) ' SSA original
- tri.angles.c = tMath.iLoS(tri.angles.b, tri.sides.c, tri.sides.b)
- tri.angles.a = tMath.TST(tri.angles.b, tri.angles.c)
- solutionInfo[2].text = "iLoS: C = ASin( c / ( b / Sin( B ) ) )"
- If (tri.angles.a = 0)
- solutionInfo[0].text = "TST: A = 180 - ( B + C )"
- End
- Else If (tri.angles.c > 0 And tri.sides.a > 0 And tri.sides.c > 0 And tri.angles.a = 0) ' SSA morph 1
- tri.angles.a = tMath.iLoS(tri.angles.c, tri.sides.a, tri.sides.c)
- tri.angles.b = tMath.TST(tri.angles.a, tri.angles.c)
- solutionInfo[0].text = "iLoS: A = ASin( a / ( c / Sin( C ) ) )"
- If (tri.angles.b = 0)
- solutionInfo[1].text = "TST: B = 180 - ( A + C )"
- End
- Else If (tri.angles.a > 0 And tri.sides.b > 0 And tri.sides.a > 0 And tri.angles.b = 0) ' SSA morph 2
- tri.angles.b = tMath.iLoS(tri.angles.a, tri.sides.b, tri.sides.a)
- tri.angles.c = tMath.TST(tri.angles.a, tri.angles.b)
- solutionInfo[1].text = "iLoS: B = ASin( b / ( a / Sin( A ) ) )"
- If (tri.angles.c = 0)
- solutionInfo[2].text = "TST: C = 180 - ( A + B )"
- End
- Else If (tri.angles.c > 0 And tri.sides.b > 0 And tri.sides.c > 0 And tri.angles.b = 0) ' SSA morph 3
- tri.angles.b = tMath.iLoS(tri.angles.c, tri.sides.b, tri.sides.c)
- tri.angles.a = tMath.TST(tri.angles.b, tri.angles.c)
- solutionInfo[1].text = "iLoS: B = ASin( b / ( c / Sin( C ) ) )"
- If (tri.angles.a = 0)
- solutionInfo[0].text = "TST: A = 180 - ( B + C )"
- End
- Else If (tri.angles.a > 0 And tri.sides.c > 0 And tri.sides.a > 0 And tri.angles.c = 0) ' SSA morph 4
- tri.angles.c = tMath.iLoS(tri.angles.a, tri.sides.c, tri.sides.a)
- tri.angles.b = tMath.TST(tri.angles.a, tri.angles.c)
- solutionInfo[2].text = "iLoS: C = ASin( c / ( a / Sin( A ) ) )"
- If (tri.angles.b = 0)
- solutionInfo[1].text = "TST: B = 180 - ( A + C )"
- End
- Else If (tri.angles.b > 0 And tri.sides.a > 0 And tri.sides.b > 0 And tri.angles.a = 0) ' SSA morph 5
- tri.angles.a = tMath.iLoS(tri.angles.b, tri.sides.a, tri.sides.b)
- tri.angles.c = tMath.TST(tri.angles.a, tri.angles.b)
- solutionInfo[0].text = "iLoS: A = ASin( a / ( b / Sin( B ) ) )"
- If (tri.angles.c = 0)
- solutionInfo[2].text = "TST: C = 180 - ( A + B )"
- End
- End
- If (tri.angles.b > 0 And tri.sides.c > 0 And tri.angles.a > 0) ' ASA original
- result = tMath.ASA(tri.angles.b, tri.sides.c, tri.angles.a, 0)
- If (tri.angles.c = 0)
- solutionInfo[2].text = "TST: C = 180 - ( A + B )"
- End
- solutionInfo[4].text = "LoS: b = Sin( B )*( c / Sin( C ) )"
- solutionInfo[3].text = "LoC: a = Sqrt( b^2 + c^2 - 2bc*Cos( A ) )"
- solution = 6
- Else If (tri.angles.c > 0 And tri.sides.a > 0 And tri.angles.b > 0) ' ASA morph 1
- result = tMath.ASA(tri.angles.c, tri.sides.a, tri.angles.b, 1)
- If (tri.angles.a = 0)
- solutionInfo[0].text = "TST: A = 180 - ( B + C )"
- End
- solutionInfo[5].text = "LoS: c = Sin( C )*( a / Sin( A ) )"
- solutionInfo[4].text = "LoC: b = Sqrt( a^2 + c^2 - 2ac*Cos( B ) )"
- solution = 7
- Else If (tri.angles.a > 0 And tri.sides.b > 0 And tri.angles.c > 0) ' ASA morph 2
- result = tMath.ASA(tri.angles.a, tri.sides.b, tri.angles.c, 2)
- If (tri.angles.b = 0)
- solutionInfo[1].text = "TST: B = 180 - ( A + C )"
- End
- solutionInfo[3].text = "LoS: a = Sin( A )*( b / Sin( B ) )"
- solutionInfo[5].text = "LoC: c = Sqrt( a^2 + b^2 - 2ab*Cos( C ) )"
- solution = 8
- Else ' Can't solve
- result = New Triangle(0, 0, 0, 0, 0, 0)
- End
- End
- If (result.angles.a <= 0 Or result.angles.b <= 0 Or result.angles.c <= 0 Or result.sides.a <= 0 Or result.sides.b <= 0 Or result.sides.c <= 0)
- solution = 1
- End
- Return result
- End
- End
- Function Main:Int()
- New KegSolver
- Return 0
- End
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement