Jump to content




[Turtle] Replacement for `go` utility

turtle utility

19 replies to this topic

#1 tele_iz_dva4a

  • New Members
  • 10 posts

Posted 02 August 2012 - 09:28 PM

Hello. I was tired of doing turtle micropositioning (through turtle.dig() or go back 1), so I made up far more usable alternative.

So

Usage: go <list of commands>, where commands are mostly 1-char wide and sometimes have prefixes.

For example, `go f100` will move turtle forward for 100 blocks. And `go mflmam` will: mine block (dig), go forward, turn left, mine block, turn around and mine one more block, having 3 blocks mined in total. This utility is extremely handy for turtle micropositioning and it command language can be used in user programs.

Okay, let's look at command language.

1) Language is concatenative, commands are executed from left to right, unknown commands are ignored.
2) Basic moves:
- f b u d -- move forward, backward, up and down respectivly
- l r a -- turn left, turn right, turn around
3) Advanced moves
- F B U D -- similar to f b u d, but will loop while block not detected. So `go F` will simply send turtle to the wall in front.
4) Digging (mining)
- m -- mine block
- M -- mine block until mined. This command is designed to mine gravel and sand, but it has 0.4s delay time.
- _m -- mine block down
- ^m ^M -- mine block up
You can also use >m for mining block in front or _M for mining down block, but there is little sense, in my opinion.
5) Placing
- >NUMBER -- place block from slot NUMBER in front
- _NUMBER -- place block from slot NUMBER down
- ^NUMBER -- place block from slot NUMBER up
6) Loops
- commandNUMBER -- repeat command NUMBER times. eg f100, r4.
- [commands]NUMBER -- repeat list of commands NUMBER times. Eg [M^Mf]15 will dig 2-height tunnel of length 15
- [commands] -- repeat commands while last command returns `true` (success). Command `go [fm]` will dig until emptyspace reached and then stop. Use this feature carefully, because of possible infinite loops

Loops support nesting. So, you can build block tower 2x2x10 with this command: `go [u[_1fl]4]10bD`. Last two chars will send turtle back to ground.

CODE v1 (canonical pastebin at http://pastebin.com/6aFnnJtx):
Spoiler


TODOs (todos will be done only on requests):
  • Ctrl-C support
  • Wireless support
  • More usefull commands (what commands?)
  • print runtime errors and warnings, print current iteration
  • better help, more examples
  • code cleanup
  • bugs elimination
  • position tracking
  • pauseresume mode
  • support new CC version (attacks, drops)


#2 xuma202

  • Members
  • 288 posts
  • LocationBonn Germany

Posted 03 August 2012 - 06:47 AM

This is awsome what about l5 will turn left and move forward 5 blocks

#3 tele_iz_dva4a

  • New Members
  • 10 posts

Posted 03 August 2012 - 07:56 AM

 xuma202, on 03 August 2012 - 06:47 AM, said:

This is awsome what about l5 will turn left and move forward 5 blocks
Maybe, but now it is matter of just one letter, you can do lf5 for your needs. Or do you mean lf5r ?

#4 xuma202

  • Members
  • 288 posts
  • LocationBonn Germany

Posted 03 August 2012 - 09:53 AM

no l5 as a replacement for lf5

#5 tele_iz_dva4a

  • New Members
  • 10 posts

Posted 03 August 2012 - 10:53 AM

 xuma202, on 03 August 2012 - 09:53 AM, said:

no l5 as a replacement for lf5
As I understand, it not very good idea. I suppose `go l` and `go l1` must do the same, but with your variant it will be hard to distinguish when just turn and when turn&go. Just turn is usefull when you are going to mine, eg `go lm`

#6 xuma202

  • Members
  • 288 posts
  • LocationBonn Germany

Posted 03 August 2012 - 12:08 PM

Why would it be hard to distinguish?

l => turn left
r => turn right
r3 => turn right and go 3 forward
l4 => turn left and go 4 forward
maybe even
l-3 => turn left and go 3 backwards

#7 tele_iz_dva4a

  • New Members
  • 10 posts

Posted 03 August 2012 - 12:43 PM

 xuma202, on 03 August 2012 - 12:08 PM, said:

Why would it be hard to distinguish?

l => turn left
r => turn right
r3 => turn right and go 3 forward
l4 => turn left and go 4 forward
maybe even
l-3 => turn left and go 3 backwards
And what about l1? It must do the same as just l.
Anyway, I'll think about it.

#8 xuma202

  • Members
  • 288 posts
  • LocationBonn Germany

Posted 03 August 2012 - 04:43 PM

Why must it? If you really need so then make it like turning left and moving n-1 blocks forward so that l2 replaces lf1

#9 Xhisor

  • New Members
  • 37 posts
  • LocationSweden

Posted 06 August 2012 - 08:23 AM

Isn't this just a
["f"] = turtle.forward()
(But with more lines, of course!)

#10 Cyclonit

  • Members
  • 50 posts
  • LocationGermany

Posted 07 August 2012 - 04:28 PM

I think the easiest and cleanest way to implement this (I did not read your code (yet ;)/>)) is to define the syntax as a string of letters. A number right behind a letter would count as a parameter for that letter. Thus "l2" would turn the turtle twice.

#11 xuma202

  • Members
  • 288 posts
  • LocationBonn Germany

Posted 07 August 2012 - 05:03 PM

 Cyclonit, on 07 August 2012 - 04:28 PM, said:

Thus "l2" would turn the turtle twice.

That would be useless because it can be replaced by "b"

#12 tele_iz_dva4a

  • New Members
  • 10 posts

Posted 08 August 2012 - 03:00 PM

 Cyclonit, on 07 August 2012 - 04:28 PM, said:

I think the easiest and cleanest way to implement this (I did not read your code (yet ;)/>)) is to define the syntax as a string of letters. A number right behind a letter would count as a parameter for that letter. Thus "l2" would turn the turtle twice.
That is done now!


 Xhisor, on 06 August 2012 - 08:23 AM, said:

Isn't this just a
["f"] = turtle.forward()
(But with more lines, of course!)
As I understand, yes, it is. But it allows you to simplify your code. For example, here is "snake"-style mine digging program:

local tArgs = { ... }
if #tArgs ~= 2 then
  print ("Usage: sptunnel <from> <to>")
  return
end
from = tonumber(tArgs[1])
to = tonumber(tArgs[2])

dofile("/go_api") -- load API

tunnel6 = "[[M^Mf_2]6a>1a]"
tunnel3 = "[[M^Mf_2]3]"

go(tunnel3..from)

if from % 2 == 0 then
  go("l"..tunnel6..(from/2).."r")
else
  go("r"..tunnel6..((from+1)/2).."l")
end

for i=(from+1),to do
  go(tunnel3..1)
  if i % 2 == 0 then
	go("l"..tunnel6..i.."r")
  else
	go("r"..tunnel6..i.."l")
  end
end

Which result to mines like this

Posted ImagePosted Image

I bet you cannot write smaller program to snake-dig, place torches and floor without using such APIs like mine one.

 xuma202, on 07 August 2012 - 05:03 PM, said:

 Cyclonit, on 07 August 2012 - 04:28 PM, said:

Thus "l2" would turn the turtle twice.

That would be useless because it can be replaced by "b"
There is `a` shortcut (turn around). Besides, if you REALLY want `l` to act as `lf`, you can add new shortcut:
...


	elseif ch == 'l' then turtle.turnLeft()
	elseif ch == 'r' then turtle.turnRight()
	elseif ch == 'a' then go("ll")

	elseif ch == 'L' then go("l"); ch = "f" -- hack to add `lf` shortcut

...
Find this code in my source and add so much shortcuts as there are symbols on keyboard! Anyway I think, that `l` is much clearer for use with just turnLeft(), and not turnLeft()+forward().

#13 TNAgent

  • New Members
  • 1 posts

Posted 10 August 2012 - 11:53 PM

I like your script very much. I think it needs one more command though.. could you add a shortcut for the command to empty the turtles inventory? Since the turtle has a 16 slot inventory the best it could mine would be a 4x4 area (assuming no empty blocks) before it would be full so it needs some way to eject that inventory near a gatherer obsidian pipe or chest for it to continue mining.

#14 Shazz

  • Members
  • 175 posts

Posted 11 August 2012 - 12:58 AM

 TNAgent, on 10 August 2012 - 11:53 PM, said:

I like your script very much. I think it needs one more command though.. could you add a shortcut for the command to empty the turtles inventory? Since the turtle has a 16 slot inventory the best it could mine would be a 4x4 area (assuming no empty blocks) before it would be full so it needs some way to eject that inventory near a gatherer obsidian pipe or chest for it to continue mining.
It can mine more than a 4x4 area. It can hold up to 1024 blocks if all the blocks are stackable. Therefore it could mine 512x2 area (assuming all blocks are stackable, there is no air) before the inventory would be completely full.

Anyways, very nice API, I think I might actually use it (I don't normally use user-made APIs).

#15 tele_iz_dva4a

  • New Members
  • 10 posts

Posted 12 August 2012 - 05:15 AM

 TNAgent, on 10 August 2012 - 11:53 PM, said:

I like your script very much. I think it needs one more command though.. could you add a shortcut for the command to empty the turtles inventory? Since the turtle has a 16 slot inventory the best it could mine would be a 4x4 area (assuming no empty blocks) before it would be full so it needs some way to eject that inventory near a gatherer obsidian pipe or chest for it to continue mining.
I have thinked about this. And I think, that dropping code is very related to "is turtle full" check and so is used at most once in any script. So it's better to do "turtle.drop()" by hands, without API.

But there are also "shortcutting" reasons, write go("f") in code is much faster than turtle.forward(), so you can add new shortcut for dropping yourself:

...
elseif ch == 'l' then turtle.turnLeft()
elseif ch == 'r' then turtle.turnRight()
elseif ch == 'a' then go("ll")

elseif ch == '.' then result = turtle.drop() -- drop current slot
...

As I see it's usage, it is like this:
for i = 1, 16 do
go(">"..i..".") -- heh, hacky-hacky.
-- first we place block, but sure it will fail (we are in front of chest)
-- so it will only do it first part - select slot
-- then dot-command (Drop command) will empty the slot
end


 Shazz, on 11 August 2012 - 12:58 AM, said:

Anyways, very nice API, I think I might actually use it (I don't normally use user-made APIs).
It is not nice API, it is ver-very-nice application and API =) Writing own tunnel-brakers is MUCH faster and easier with it.

#16 ChunLing

  • Members
  • 2,027 posts

Posted 11 October 2012 - 04:27 AM

This is a very good program, which deserves a bump because it can do pretty much all the simple things like excavating or tunneling.

I did a rewrite of it to better fit my own needs (mainly, I made it part of the program that I'm currently using for pretty much all my turtle control needs). One thing I did, I changed the multiple elseif then sections to a single elseif and a table look-up (this also avoids calling the more complicated loop parsing and execution functions, since I put them after the simple command look-up). This also allowed eliminating some of the less useful functions.

I feel like the use of a look-up table rather than a long series of elseif then statements not only improves performance (though this is hardly an issue) but also makes it easier to extend/customize the function to given needs, like supporting extended API functions.
Spoiler
You can see that the table of indexed functions I use up top contains functions other than the standard turtle API functions. Having a section like that means that the program can be extended/customized easily without anyone having to mess with the core of your program.

#17 Sebra

  • Members
  • 726 posts

Posted 11 October 2012 - 02:36 PM

Nice function :P/>
I think it should be able to do anything from turtle api. Definitely suck functions. Detect and compare too. Most turtle functions return boolean. Others can be "corrected".
In my humble opinion selection deserves to be separate command.
Also tiny program to pass it's arguments to this function would be good.

Agree?

#18 ChunLing

  • Members
  • 2,027 posts

Posted 11 October 2012 - 03:58 PM

The revised version I posted allows pretty near all of that by using a character indexed table for the commands.
Spoiler

rctfncs functions repack the basic turtle functions with a bit of improved functionality (for my purposes). You can edit all the available functions (and what character represents them) easily, just add "x=yrfunc" to the table (x represents the character you want to use to call the function, yrfunc is the name of the function).

Because the program itself has limited support for conditionals, I didn't see a need to put detect/compare functions. The rctfncs dfd, dup, and ddn are designed with making sure a turtle moves in the indicated direction if at all possible, destroying/killing anything in the way (note, that includes players). If you're going to load it into the api and call it from another program the way tele_iz_dva4a did in the above example, then using tArgs rather than doing what I did makes sense (it's easy to shift the usage back, I just like being able to see a reference for how to compose the command string while I'm composing it--I guess I could use tArgs and just "if not tArgs[1] then" display the input message if not tArgs[1] then). That way you could use it as an api load for another function (which would support the conditionals you suggest).

#19 tele_iz_dva4a

  • New Members
  • 10 posts

Posted 26 October 2012 - 03:17 PM

Hi ChunLing, realy 10x for improving code. I am quite novice to Lua, so...
IMO your code is too condensed. Cuttin' length to lngth is escpecially funny =)
Also, making API is possible, I often import this (slightly modified) script and mix standard code and go() shortcuts.

#20 ChunLing

  • Members
  • 2,027 posts

Posted 26 October 2012 - 06:36 PM

Yes, I originally thought about making an API of the rctfncs I use. I decided against it because for now I want to have a single program, both for use by people who just download one and for myself to be able to edit the program "on the fly" without having to change everything.

When the functions are all in a settled state and I'm using them in more than just one program, I'll probably put them into an API. But I'm still tuning this functions and still only use them in the one turtle program.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users