Calculadora 2
forked from Black Graph (diff: 1298)
code is dirty ^^ you can: sin() cos() tan() x ( ) + - * / ^ pi ² ³
ActionScript3 source code
/**
* Copyright Thy ( http://wonderfl.net/user/Thy )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/5wOq
*/
// forked from Thy's Black Graph and http://wonderfl.net/c/jW4u
// code is dirty ^^
// you can: sin() cos() tan() x ( ) + - * / ^ pi ² ³
package
{
import flash.events.KeyboardEvent;
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
//
//[SWF(width=465,height=465,frameRate=465, backgroundColor="#000000")]
/**
* ...
* @author Thi
*/
public class Main extends Sprite
{
// Storage for all calculators (havent added to functionaly add more caolculators, yet)
private var calculators:Vector.<Calculadora> = new Vector.<Calculadora>(1)
// Storage for x, y, and others custom values. ["x", 0,"y",0,...]
private var libraly:Array
// temp var calculator
private var calc:Calculadora
// Result TF
private var TF:TextField
private var delay:int
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// create the library. Variables who will be used in some calculator who uses that library
libraly = ["x", 1, "y", 2, "pi", Math.PI]
// Text for result
TF = new TextField()
TF.autoSize = TextFieldAutoSize.LEFT
TF.y = 40
TF.text = "Result"
stage.addChild(TF)
// create a calculator
calc = new Calculadora(libraly, "1 + 2 * 3 ^ 4")//".1*x^3-x*4+.1x^2-(.0045*x^4)", "y")
addChild(calc)
stage.addEventListener(KeyboardEvent.KEY_DOWN, changed)
stage.addEventListener(Event.ENTER_FRAME, ef)
// listener
// make an first run for the calculator, just to show some result at the beggining
justShowResult()
}
private function ef(e:Event):void
{
if(++delay == 0)
{
calc.convert() // converts the expression for a 'readable' expression
calc.convert_to_rpn() // convert the expression for a way to calculate more easily
calc.rpn() // just calculate (+,-,*,/,^)
TF.text = String(calc.Return)
}
}
// you can ignore this function
private function justShowResult():void
{
calc.convert()
calc.convert_to_rpn()
calc.rpn()
TF.text = String(calc.Return)
}
private function changed(e:KeyboardEvent):void
{
delay = -5
}
}
}
import flash.events.KeyboardEvent;
//package
//{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TextEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
/**
* ...
* @author Thi
*/
/*public*/ class Calculadora extends Sprite
{
// public variables
public var TF:TextField
public var t:String
public var libraly:Array
public var Return:Number
//
public var upd:Boolean // updated the expression
public var pos:Boolean // updated the 'result text', then must update the position
// result TF
public var tf:TextField
public var r:String
// '=' text
private var eq:Sprite
// text stuff
private var format:TextFormat
public function Calculadora(libraly:Array = null, t:String = null)
{
this.libraly = libraly; // libraly, used for variables, example 'x = 0' or 'hello = 1'
this.t = t; // the input expression, when this calss is called
// init format
format = new TextFormat("Arial", 20)
// init text
TF = new TextField()
TF.defaultTextFormat = format
TF.autoSize = TextFieldAutoSize.LEFT
TF.type = "input"
TF.border = true
TF.borderColor = 0xC0C0C0
TF.textColor = 0
TF.text = t
//TF.text = "IUHDSOIUDSANMOIDJASDIOSAMOM"
//
TF.x = 10
TF.y = 10
// add to Sprite content
this.addChild(TF)
// add text change listener
// sets 'updated' to false
upd = false
}
// RPN calculation
// storage the elements when converting
private var ele:Array
private var num:Array // used for sotage big numbers or words (so 'HI' wont be storage as 'H','I', but "HI")
// int for looping process
private var i:int, j:int
//
private var length:int
private var char:String, last:String
// function who convert 'strings' to 'expressions'
public function convert():void
{
// clear arrays and integers and errorPreventing (Parentesis stuff)
ele = []
num = []
i = j = 0
preventError = false
// setup length
t = TF.text
length = t.length
while (i < length)
{
char = t.charAt(i)
if (Number(char) || char == "0")
{
// lats char is equal to the last char from elements
last = ele[ele.length - 1]
if (last == ")")
{
// push an multiplication (* symbol)
ele.push("*")
}
//
j = i
while (Number(char) || char == "," || char == "." || char == "0")
{
num.push(char)
++j
char = t.charAt(j)
}
// so the '2 char or more' number has been 'built'
// add the 'big number' to the array
ele.push(num.join(""))
num = [] // clear
// the loop continues
i = j - 1
j = 0 // clear j
} else if (char == "*" || char == "+" || char == "-" || char == "/" || char == "^")
{
ele.push(char)
} else if (char == "." || char == ",")
{
// create a big number, for example: .2 -> 0.2
num.push("0")
num.push(".")
//
j = i
if (Number(char) || char == "0")
{
while (Number(char) || char == "0")
{
num.push(char)
++j
char = t.charAt(j)
}
// 'big number' ready
// make the array became a single 'number', then add it to elements
ele.push(num.join(""))
// keep looping..
i = j-1
// clear
num = []
j = 0
}
} else if (char == "(" || char == "[" || char == "{")
{
preventError = true
// take the last element
last = ele[ele.length-1]
if (last != "+" && last != "-" && last != "*" && last != "/" && last != "^" && last != "undefined" && last != null && last != "sin" && last != "cos" && last != "tan")
{
// add an multiplication
ele.push("*")
}
// then finnaly add the parentesis
ele.push("(")
} else if (char == "²")
{
ele.push("^")
ele.push("2")
} else if (char == "³")
{
ele.push("^")
ele.push("3")
} else if (char == ")" || char == "]" || char == "}")
{
ele.push(")")
// so.. convert every ([{}]) -> ((()))
} else if (char != " ")
{
last = ele[ele.length -1]
if (last != "+" && last != "-" && last != "*" && last != "/" && last != "^" && last != "undefined" && last != "(" && last != "[" && last != "{" && last != null && last != "²" && last != "³" )
{
// add an multiply
ele.push("*")
}
j = i
while (char != "," && char != "." && char != "+" && char != "-" && char != "*" && char != "/" && char != "^" && char != "(" && char != "[" && char != "{" && char != ")" && char != "]" && char != "}" && char != " " && char != null && char != "undefined" && char != "" && char != "²" && char != "³")
{
num.push(char)
++j;
char = t.charAt(j)
}
// so the 'big word' has been formed. and then pushed at elements.
// but before that see if its angle relactioned
var temp:String = num.join("")
if (temp == "sen" || temp == "seno")
{
temp = "sin"
} else if (temp == "cosseno")
{
temp = "cos"
} else if (temp == "tangent" || temp == "tangente" || temp == "tgt" || temp == "tg")
{
temp = "tan"
}
ele.push(temp)
// clear
num = []
temp = ""
// keep loopin'
i = j-1
}
++i
}
}
// so after this function, i have the expression more organized
// but still an array with strings, like: [1,+,1] or [1,-,VAR,+,20,*,(,aVALUE,)]
private var result:Array // store elements used on RPN calculation. It will last 1 element, the result
private var calculation:Array // store elements that relacionates to the 'right order'.. like '*' first than '+'
private var result2:Array // just a copy from result
public function convert_to_rpn():void
{
// clear stuff
result = []
calculation = []
i = j = 0
//
while (i < ele.length)
{
// its not really a single char. can be an word or large number
char = ele[i]
if (Number(char) || char == "0")
{
result.push(char)
} else if (char == "(")
{
calculation.push(char)
} else if (char == "+" || char == "-" || char == "*" || char == "/" || char == "^" || char == "sin" || char == "cos" || char == "tan")
{
calculation.push(char)
// call a function that organizes the order
Nopr()
} else if (char == ")")
{
calculation.push(char)
close_parentesis()
} else
{
result.push(char)
}
// loopin' 'chars'
++i
}
// now add 'calculation' array (reverse) to the result array
j = calculation.length
while (j > 0)
{
if (calculation[j - 1] != "")
{
result.push(calculation[j-1])
}
--j
}
// keep looping thought other 'chars'
result2 = result
}
private var level1:uint, level2:uint
private function Nopr():void
{
if (char == "+" || char == "-")
{
level1 = 1;
} else if (char == "*" || char == "/")
{
level1 = 2;
} else if (char == "^")
{
level1 = 4;
} else if (char == "sin" || char == "cos" || char == "tan")
{
level1 = 8
}
if (calculation[calculation.length - 2] == "+" || calculation[calculation.length - 2] == "-")
{
level2 = 1;
} else if (calculation[calculation.length - 2] == "*" || calculation[calculation.length - 2] == "/")
{
level2 = 2;
} else if (calculation[calculation.length - 2] == "^")
{
level2 = 3;
} else if (calculation[calculation.length - 2] == "sin" || calculation[calculation.length - 2] == "cos" || calculation[calculation.length - 2] == "tan")
{
level2 = 4;
} else
{
level2 = 0;
}
if (level1 <= level2)
{
result.push(calculation[calculation.length-2]);
calculation.splice(calculation.length - 2, 1);
// repeats
Nopr();
}
}
private var preventError:Boolean
private function close_parentesis():void
{
if (calculation[calculation.length - 2] != "(")
{
result.push(calculation[calculation.length - 2])
calculation.splice(calculation.length - 2, 1)
if (preventError)
{
close_parentesis()
}
} else
{
calculation.splice(calculation.length-2,2)
}
}
private var n0:Boolean, n1:Boolean // if vars are number
private var operator:Boolean
public function rpn():void
{
result = result2.concat()
i = 0
while (i < result.length)
{
char = result[i]
if (result.length > 1)
{
if (char == "+")
{
if (Number(result[i - 2]) || result[i - 2] == 0)
{
result[i] = Number(result[i - 2]) + Number(result[i - 1])
result.splice(i - 2, 2)
--i;
} else
{
result[i] = Number(result[i - 1])
result.splice(i - 1, 1)
}
--i;
} else if (char == "-")
{
if (Number(result[i - 2]) || result[i - 2] == 0)
{
result[i] = Number(result[i - 2]) - Number(result[i - 1])
result.splice(i - 2, 2)
--i;
} else
{
result[i] = - Number(result[i - 1])
result.splice(i - 1, 1)
}
--i;
} else if (char == "*")
{
result[i] = Number(result[i - 2]) * Number(result[i - 1])
result.splice(i - 2, 2)
--i; --i;
} else if (char == "/")
{
result[i] = Number(result[i - 2]) / Number(result[i - 1])
result.splice(i - 2, 2)
--i; --i;
} else if (char == "^")
{
result[i] = Math.pow(Number(result[i - 2]), Number(result[i - 1]))
result.splice(i - 2, 2)
--i; --i;
} else if (!Number(char) && char != "0")
{
if (char == "sin")
{
result[i] = Math.sin(Number(result[i - 1]))
result.splice(i - 1, 1)
--i
} else if (char == "cos")
{
result[i] = Math.cos(Number(result[i - 1]))
result.splice(i - 1, 1)
--i
} else if (char == "tan")
{
result[i] = Math.tan(Number(result[i - 1]))
result.splice(i - 1, 1)
--i
} else
{
// then char is a word, so now that word is search in the referenced libraly
j = 0
while (j < libraly.length)
{
if (char == libraly[j])
{
++j
result[i] = libraly[j]
--i
break;
}
++j; ++j;
}
// the index of the value has been found (j)
if (j == 0 && libraly[0] != char)
{
++i
}
}
}
} else if (!Number(char) && char != "0")
{
if (char == "sin")
{
result[i] = Math.sin(Number(result[i - 1]))
result.splice(i - 1, 1)
--i
} else if (char == "cos")
{
result[i] = Math.cos(Number(result[i - 1]))
result.splice(i - 1, 1)
--i
} else if (char == "tan")
{
result[i] = Math.tan(Number(result[i - 1]))
result.splice(i - 1, 1)
--i
} else {
// then char is a word, so now that word is search in the referenced libraly
j = 0
while (j < libraly.length)
{
if (char == libraly[j])
{
++j
result[i] = libraly[j]
--i
break;
}
++j; ++j;
}
// the index of the value has been found (j)
if (j == 0 && libraly[0] != char)
{
++i
}
}
}
++i
}
// the returnable result, in (:Number)
Return = Number(result[0])
// changed the result variable, like 'y = 1*2+1', It will set 'y' (from libraly) to 3 (:Number)
// then char is a word, so now that word is search in the referenced libraly
/*i = 0, j = 0
while (i < libraly.length)
{
if (tf.text == libraly[i])
{
++i
libraly[i] = Return
j = 1
break;
}
++i; ++i;
}
if (j == 0)
{
this just means that the word doesnt really exist in the libraly, so we create it
libraly.push(tf.text)
libraly.push(Return)
}*/
// now yes, this calculation thing ends :)
}
}
//}
//package
//{
import flash.display.Graphics;
import flash.display.Sprite;
/**
* ...
* @author Thi
*/
/*public*/ class Graph extends Sprite
{
public var g:Graphics, X:String, Y:String
private var libraly:Array
private var valueX:Number, valueY:Number, scale:Number
public function Graph(libraly:Array = null, X:String = "x", Y:String = "y", scale:Number = 10)
{
this.libraly = libraly
this.X = X
this.Y = Y
this.scale = scale
g = this.graphics
g.lineStyle(1, 0xFF0000)
g.moveTo( -40, 250)
}
public function clear():void
{
g.clear()
g.lineStyle(1, 0xFF0000)
g.moveTo( -40, 250)
}
private var i:int
public function line():void
{
if (!Number(X) && X != "0")
{
i = 0
while (i < libraly.length)
{
if (libraly[i] == X)
{
break;
}
++i; ++i
}
valueX = Number(libraly[++i])
} else
{
valueX = Number(X)
}
if (!Number(Y) && Y != "0")
{
i = 0
while (i < libraly.length)
{
if (libraly[i] == Y)
{
break;
}
++i; ++i
}
valueY = Number(libraly[++i])
} else
{
valueY = Number(Y)
}
//
g.lineTo(valueX * scale + 232, 232 - valueY * scale)
//g.lineTo(mouseX, mouseY)
}
public function move():void
{
if (!Number(X) && X != "0")
{
i = 0
while (i < libraly.length)
{
if (libraly[i] == X)
{
break;
}
++i; ++i
}
valueX = Number(libraly[++i])
} else
{
valueX = Number(X)
}
if (!Number(Y) && Y != "0")
{
i = 0
while (i < libraly.length)
{
if (libraly[i] == Y)
{
break;
}
++i; ++i
}
valueY = Number(libraly[++i])
} else
{
valueY = Number(Y)
}
//
g.moveTo(valueX * scale + 232, 232 - valueY * scale)
//g.lineTo(mouseX, mouseY)
}
}
//}
//package
//{
import flash.display.Graphics;
import flash.display.Sprite;
/**
* ...
* @author Thi
*/
/*public*/ class Axis extends Sprite
{
public var cx:Number, cy:Number, range:Number, number:Number
private var g:Graphics
public function Axis(cx:Number = 0, cy:Number = 0, range:Number = 0, number:Number = 0)
{
this.cx = cx
this.cy = cy
this.range = range
this.number = number
g = this.graphics
draw()
}
public function draw():void
{
g.clear()
g.lineStyle(1, 0xFFFFFF)
//
g.moveTo(0, cy)
g.lineTo(cx * 2, cy)
g.moveTo(cx, 0)
g.lineTo(cx, cy * 2)
//
g.lineStyle(1, 0xFFFFFF, .2)
var i:int = 0
while (i < 2 * number)
{
g.moveTo(i*range*.5, 0)
g.lineTo(i*range*.5,cy*2)
g.moveTo(0, i*range*.5)
g.lineTo(cx*2,i*range*.5)
++i
}
}
}
//}