1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
|
let doc = """
Naval Fate.
Usage:
naval_fate ship new <name>...
naval_fate ship <name> move <x> <y> [--speed=<kn>]
naval_fate ship shoot <x> <y>
naval_fate mine (set|remove) <x> <y> [--moored | --drifting]
naval_fate (-h | --help)
naval_fate --version
Options:
-h --help Show this screen.
--version Show version.
--speed=<kn> Speed in knots [default: 10].
--moored Moored (anchored) mine.
--drifting Drifting mine.
"""
import std/[strutils, sequtils]
import docopt
type CustomInt* = distinct int
# You can name a proc `to<type name>` in order to have the dispatcher be able
# to marshall your custom types.
proc toCustomInt*(v: Value): CustomInt =
CustomInt(parseInt($v))
import docopt/dispatch
let args = docopt(doc, version = "Naval Fate 2.0")
# Define procedures with parameters named the same as the arguments
proc newShip(name: seq[string]) =
for ship in name:
echo "Creating ship $#" % ship
proc moveShip(name: string, x, y: int, speed: int) =
echo "Moving ship $# to ($#, $#) at $# kn".format(
name, x, y, speed)
proc shootShip(x, y: CustomInt) = # This works because we have `toCustomInt` defined above
echo "Shooting ship at ($#, $#)".format(x.int, y.int)
# These procedures are not used below, but could be used similar to those above
proc setMine(x, y: int, moored, drifting: bool) =
echo "Setting $# mine at ($#, $#)".format(
(if moored: "moored" elif drifting: "drifting" else: ""),
x, y)
proc removeMine(x, y: int) =
echo "Removing mine at ($#, $#)".format(x, y)
# This procedure is named the same as an argument so it can be passed directly
# to `dispatchProc` without supplying a list of arguments to match. When no
# list is supplied it will simply check for an argument named the same as the
# procedure.
proc mine(x, y: int, moored, remove: bool) =
if remove:
echo "Removing mine at ($#, $#)".format(x, y)
else:
echo "Setting $# mine at ($#, $#)".format(
(if moored: "moored" else: "drifting"),
x, y)
if args.dispatchProc(newShip, "ship", "new") or # Runs newShip when "ship" and "new" is set
args.dispatchProc(moveShip, "ship", "move") or # Runs newShip when "ship" and "move" is set
args.dispatchProc(shootShip, "ship", "shoot") or # Runs newShip when "ship" and "shoot" is set
args.dispatchProc(mine): # Runs mine when "mine" is set
echo "Ran something"
else:
echo doc
# Instead of the `mine` dispatcher above these could be used instead
#args.dispatchProc(setMine, "mine", "set")
#args.dispatchProc(removeMine, "mine", "remove")
|