Need help in using turtle module - turtle-graphics

So I'm writing a program using the turtle module. I have 2 questions:
I have 4 turtles. How can I make their names show up on the screen while drawing?
After I finish drawing, how can I exit one screen and open another within the same program?

I have 4 turtles. How can I make their names show up on the screen
while drawing?
Sure, here's a crude example:
from random import choice
from turtle import Turtle, Screen
NAMES = ['Donnie', 'Raph', 'Mickey', 'Leo']
SPEEDS = ["slowest", "slow", "normal", "fast", "fastest"]
FONT = ("Arial", 12, "normal")
MAGNIFICATION = 5
STAMP_SIZE = 20
MAXIMUM_SPEED = 10
LINE_OFFSET = 50
screen = Screen()
WINDOW_WIDTH = screen.window_width()
START, FINISH = LINE_OFFSET - WINDOW_WIDTH//2, WINDOW_WIDTH//2 - (LINE_OFFSET + MAXIMUM_SPEED)
turtles = {name: Turtle(shape='turtle') for name in NAMES}
for offset, turtle in enumerate(turtles.values(), start=-len(NAMES)//2):
turtle.turtlesize(MAGNIFICATION)
turtle.color("black", "white")
turtle.penup()
turtle.goto(START, offset * MAGNIFICATION * STAMP_SIZE)
turtle.speed(choice(SPEEDS))
turtle.write("", font=FONT) # dummy write for 1st undo
winner = False
while not winner:
for name, turtle in turtles.items():
turtle.undo() # unwrite name
turtle.forward(turtle.speed() + 1)
turtle.write(name, font=FONT) # rewrite name
if turtle.xcor() >= FINISH:
winner = True
break
screen.exitonclick()
To do better with respect to text centering and eliminating flicker, we would need one or more extra invisible turtles to just handle the text. However, when the turtles turn, the text won't turn with them, it'll always be horizontal.

Related

Can't calculate the right Volume RSI in MQL4 with a functioning Pine-Script Example

I want to "translate" a Pine-Script to MQL4 but I get the wrong output in MQL4 compared to the Pine-Script in Trading-view.
I wrote the Indicator in Pine-Script since it seems fairly easy to do so.
After I got the result that I was looking for I shortened the Pine-Script.
Here the working Pine-Script:
// Pinescript - whole Code to recreate the Indicator
study( "Volume RSI", shorttitle = "VoRSI" )
periode = input( 3, title = "Periode", minval = 1 )
VoRSI = rsi( volume, periode )
plot( VoRSI, color = #000000, linewidth = 2 )
Now I want to translate that code to MQL4 but I keep getting different outputs.
Here is the MQL4 code I wrote so far:
// MQL4 Code
input int InpRSIPeriod = 3; // RSI Period
double sumn = 0.0;
double sump = 0.0;
double VoRSI = 0.0;
int i = 0;
void OnTick() {
for ( i; i < InpRSIPeriod; i++ ) {
// Check if the Volume is buy or sell
double close = iClose( Symbol(), 0, i );
double old_close = iClose( Symbol(), 0, i + 1 );
if ( close - old_close < 0 )
{
// If the Volume is positive, add it up to the positive sum "sump"
sump = sump + iVolume( Symbol(), 0, i + 1 );
}
else
{
// If the Volume is negative, add it up to the negative sum "sumn"
sumn = sumn + iVolume( Symbol(), 0, i + 1 );
}
}
// Get the MA of the sump and sumn for the Input Period
double Volume_p = sump / InpRSIPeriod;
double Volume_n = sumn / InpRSIPeriod;
// Calculate the RSI for the Volume
VoRSI = 100 - 100 / ( 1 + Volume_p / Volume_n );
// Print Volume RSI for comparison with Tradingview
Print( VoRSI );
// Reset the Variables for the next "OnTick" Event
i = 0;
sumn = 0;
sump = 0;
}
I already checked if the Period, Symbol and timeframe are the same and also have a Screenshoot of the different outputs.
I already tried to follow the function-explanations in the pine-script for the rsi, max, rma and sma function but I cant get any results that seem to be halfway running.
I expect to translate the Pine-Script into MQL4.
I do not want to draw the whole Volume RSI as a Indicator in the Chart.
I just want to calculate the value of the Volume RSI of the last whole periode (when new candel opens) to check if it reaches higher than 80.
After that I want to check when it comes back below 80 again and use that as a threshold wether a trade should be opened or not.
I want a simple function that gets the Period as an input and takes the current pair and Timeframe to return the desired value between 0 and 100.
Up to now my translation persists to provide the wrong output value.
What am I missing in the Calculation? Can someone tell me what is the right way to calculate my Tradingview-Indicator with MQL4?
Q : Can someone tell me what is the right way to calculate my Tradingview-Indicator with MQL4?
Your main miss of the target is in putting the code into a wrong type of MQL4-code. MetaTrader Terminal can place an indicator via a Custom Indicator-type of MQL4-code.
There you have to declare so called IndicatorBuffer(s), that contain pre-computed values of the said indicator and these buffers are separately mapped onto indicator-lines ( depending on the type of the GUI-presentation style - lines, area-between-lines, etc ).
In case you insist on having a Custom-Indicator-less indicator, which is pretty legal and needed in some use-cases, than you need to implement you own "mechanisation" of drawing lines into a separate sub-window of the GUI in the Expert-Advisor-code, where you will manage all the settings and plotting "manually" as you wish, segment by segment ( we use this for many reasons during prototyping, so as to avoid all the Custom-Indicator dependencies and calling-interface gritty-nitties during the complex trading exosystem integration - so pretty well sure about doability and performance benefits & costs of going this way ).
The decision is yours, MQL4 can do it either way.
Q : What am I missing in the Calculation?
BONUS PART : A hidden gem for improving The Performance ...
In either way of going via Custom-Indicator-type-of-MQL4-code or an Expert-Advisor-type-of-MQL4-code a decision it is possible to avoid a per-QUOTE-arrival re-calculation of the whole "depth" of the RSI. There is a frozen-part and a one, hot-end of the indicator line and performance-wise it is more than wise to keep static records of "old" and frozen data and just update the "live"-hot-end of the indicator-line. That saves a lot of the response-latency your GUI consumes from any real-time response-loop...

Spawning Sprites In Space Invaders

I'm currently trying to spawn aliens for a space invaders game I'm creating in class. I'm using a while loop with a counter to adjust an array to a given variable value. This way I can increase the number of aliens without any re-writing. The problem is, although my aliens spawn, the x position is not increasing as I would like it to. I only see one Alien on the screen so I've concluded that they are all spawning, but only with a 1-pixel difference, therefore unnoticeable. Here's what I have so far, any help would be greatly appreciated!
//Add and display given amount of aliens...
while (alienAmount > displayLoopCounter) {
aliens.append(SKSpriteNode(texture: SKTexture(imageNamed: "ClassicAlien")))
self.addChild(aliens[displayLoopCounter])
//Location
aliens[displayLoopCounter].position.y = CGFloat(-15)
aliens[displayLoopCounter].position.x = CGFloat(displayLoopCounter + 25)
print(aliens[displayLoopCounter].position.x)
displayLoopCounter += 1
print(displayLoopCounter)
//Have we run out of aliens yet?
if displayLoopCounter > alienAmount {
displayAliens = false
}
You just need to change the spacing you're setting between aliens. In other terms, you need to set the x position of each alien sprite to have more spacing between them. Currently, you are just adding displayLoopCounter to the x position of each alien. Since displayLoopCounter only increases one at a time, the aliens are all spawned with a 1-pixel difference to each other. If we want a bigger difference, we will need to multiply displayLoopCounter by our intended spacing so that we get that spacing between each alien.
You can just set a spacingBetweenAliens variable with a numeric type (such as Int or CGFLoat or Double) and change this line:
aliens[displayLoopCounter].position.x = CGFloat(displayLoopCounter + 25)
To this:
let basePosition = displayLoopCounter * spacingBetweenAliens
aliens[displayLoopCounter].position.x = CGFloat(basePosition + 25)
This way, the aliens will be spawned with the value of spacingBetweenAliens in pixels between them.

Distribute 4 SKSpriteNodes along SkScene Width programmatically

I know scene coordinates are (0,0) at center so how can i distribute 4 SKNodes along the width using a for loop
for index 1...4 {
let node = SKNode()
node.postion = evenly distribute along the scene width. who can i do it?
}
You could use the width of the scene divided by the number of nodes minus 1. This would then be multiplied by the index minus 1, then added to the minimum x value of your scene.
let widthRange = scene.frame.maxX - scene.frame.minX
for index 1...4 {
let node = SKNode()
node.postion = scene.frame.minX + widthRange/(4-1) * (index-1)
}
This should place each node an equal distance away from each other along the width of the scene, starting from each edge.
If your index for the for loop doesn't start at 1, the code would need to be modified to something like this:
let widthRange = scene.frame.maxX - scene.frame.minX
var counter = 0
for index 352...356 {
let node = SKNode()
node.postion = scene.frame.minX + widthRange/(4-1) * counter
counter+=1
}
If you're unsure of which version to use, use the second version, as it's less reliant on the format of the for loop (as long as you reset counter to 0 before every time you use this).
If you need any clarifications as to what does what, feel free to ask.
Edit
This should clarify what the code actually does.
let widthRange = scene.frame.maxX - scene.frame.minX is used to get the size of the scene, then set it to a variable that is used later. Making this a variable is sort of optional as you could just use the scene size, however I put it this way so it's less messy.
var counter = 0 simply makes a counter variable, that's used in the for-loop, to place the nodes. Make sure to set it to 0 before every time you run the loop. counter+=1 is then used later so each node is multiplied by an increasing value, which creates the different x-positions. (I'll get into that later)
node.postion = scene.frame.minX + widthRange/(4-1) * counter is the complicated line. First, I use scene.frame.minX to start placement from the lowest width/x-position. widthRange/(4-1) is a little harder to understand. It uses the scenes width (from earlier), then divides by one less than the amount of nodes. The best way to understand this, is that to cut a rectangle (only in a single direction) so it has 2 cuts through it (2 of the nodes), and 2 edges (the other 2 nodes), you would need 3 sections. (The rectangle would be cut into 3). This gets the distance between each node. The pattern of #ofNodes-1 follows for every amount of nodes. The * counter part is the part that makes the node's x-position actually change. Since every time the loop is gone through, counter increases by 1 (starting at 0) the amount of "sections" from before (widthRange/(4-1)) is increased by 1.

Background infinite using corona sdk

I'm trying to scroll side a background in corona sdk (infinity background)
I used two images repeated (854x176).
I tried this function:
function mov(self, event)
if self.x < -854 then
self.x = 854
else
self.x = self.x - self.speed
end
end
it's working just fine but the problem that a small white space occurred between repetitions.
Is there a better way to do this?
One way of doing this would be to take advantage of Graphics 2.0 Engine's feature called repeating fills.
Here are the steps:
Set the default texture wrapping mode for x (you could do the same for y too):
display.setDefault("textureWrapX", "mirroredRepeat")
The modes for wrapping are:
"clampToEdge" - (default) clamped fill won't repeat
"repeat" - fill is repeated as if same tiles were placed side by side
"mirroredRepeat" - fill is repeated in a mirrored pattern, each tile being a mirror image of the one next to it
Create a rectangle the size of the background you want to have, eg. full screen
local background = display.newRect(display.contentCenterX, display.contentCenterY, 320, 480)
Fill your display object with your background image
background.fill = {type = "image", filename = "background.jpg"}
Animate it using whatever method fits your app. Below's just one way:
local function animateBackground()
transition.to(background.fill, {time=5000, x=1, delta=true, onComplete=animateBackground})
end
animateBackground()
Here you simply run transition on x property of background.fill object, delta=true indicating that we're rather using changes in x value, not final ending values (see here).
Play with the values for time, x, set delta to false, play with wrapping modes, just to see what effect it has on animation. You might even accidentally discover some cool effect which you might want to use later...
Check this excellent tutorial by Brent Sorrentino, who goes through more details on fills. Additionally, see sample code in CoronaSDK under Graphics-Premium/PatternFill.
Full code:
display.setDefault("textureWrapX", "mirroredRepeat")
local background = display.newRect(display.contentCenterX, display.contentCenterY, 320, 480)
background.fill = {type = "image", filename = "background.jpg" }
local function animateBackground()
transition.to( background.fill, { time=5000, x=1, delta=true, onComplete=animateBackground } )
end
animateBackground()

Text alignment to left in Corona

My problem is that I can't align my text to left. I need to set a position where the text will start and it will go to the left and it wont be centered. Its like in html, you make position and it goes from that position to the right, eventually it makes another line. Maybe a picture example will make you understand better because its hard to describe it.
How it should look and where it should start all the time if I add more text it should just continue to the right.
How it looks if I add more text, and that's not how I want it
Here's a bit of the code
text = display.newText("Fair", 0, 0, "HelveticaNeue-Light", 22)
text.x = halfW - 300
text.y = halfH + 110
text.align = "left"
Are you using the Current Public Release (2014.2100) + ?
Try using text.anchorX = 0 instead of text.align = "left"
So anchorX = .5 is same as "middle" and anchorX = 1 is same as "right".

Resources