aboutsummaryrefslogtreecommitdiffstats
path: root/test/rl.lua
blob: 35a831e76e4fbbcf4666225ee656a7a594e17fac (plain) (blame)
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
require 'curses'
require 'signal'

-- globals {{{
local map, rows, cols
local colors = {
    "black", "green",
    "red",   "cyan",
    "white", "magenta",
    "blue",  "yellow"
}
-- }}}

-- helpful functions {{{
local function pline(str)
    curses.addstr({y = 0, x = 0}, str)
    curses.clrtoeol()
end

local function botl(str)
    curses.addstr({y = rows - 1, x = 0}, str)
    curses.clrtoeol()
end

local function cleanup(sig)
    curses.clear()
    curses.endwin()
    if sig then
        signal.signal(sig, "default")
        signal.raise(sig)
    end
end
-- }}}

-- curses initialization {{{
curses.initscr();
curses.start_color();
curses.use_default_colors();
curses.setup_term{nl = false, cbreak = true, echo = false, keypad = true}
for _, color in ipairs(colors) do
    curses.init_pair(color, color)
end
-- }}}

-- cleanup on signals {{{
signal.signal("TERM", cleanup)
signal.signal("INT",  cleanup)
-- }}}

-- get the term size and the size of the map we want to draw {{{
rows, cols = curses.getmaxyx()
map = {ul = {x = 0, y = 1}, lr = {x = cols - 1, y = rows - 3}}
map.w = map.lr.x - map.ul.x + 1
map.h = map.lr.y - map.ul.y + 1
-- }}}

-- draw the screen {{{
curses.clear()
for i = map.ul.y, map.lr.y do
    curses.addstr({y = i, x = map.ul.x}, ("."):rep(map.w))
end
-- }}}

-- initialize the character {{{
local char = {
    x = math.random(map.ul.x, map.lr.x),
    y = math.random(map.ul.y, map.lr.y),
    move = function(self, offset)
        if self.x + offset.x < map.ul.x or
           self.x + offset.x > map.lr.x or
           self.y + offset.y < map.ul.y or
           self.y + offset.y > map.lr.y then
            return 0
        else
            self.x = self.x + offset.x
            self.y = self.y + offset.y
            return 1
        end
    end,
    draw = function(self)
        curses.addch(self, "@", {bold = true})
        curses.move(self)
    end,
    erase = function(self)
        curses.addch(self, ".")
        curses.move(self)
    end
}
-- }}}

-- movement commands {{{
local directions = {
    y =     {x = -1, y = -1},
    h =     {x = -1, y = 0},  left =  {x = -1, y = 0},
    b =     {x = -1, y = 1},
    k =     {x = 0,  y = -1}, up =    {x = 0, y = -1},
    ["."] = {x = 0,  y = 0},  s =     {x = 0, y = 0},
    j =     {x = 0,  y = 1},  down =  {x = 0, y = 1},
    u =     {x = 1,  y = -1},
    l =     {x = 1,  y = 0},  right = {x = 1, y = 0},
    n =     {x = 1,  y = 1},
}
-- }}}

-- main loop {{{
local turns = 0
while true do
    botl("T:" .. turns)
    char:draw()
    local c = curses.getch()
    char:erase()
    pline("")
    if directions[c] then
        turns = turns + char:move(directions[c])
    elseif (c == "Q") then
        break
    else
        if c == "\n" then c = "^J" end
        if c == "\r" then c = "^M" end
        pline("Unknown command '" .. c .. "'")
    end
end
-- }}}

-- cleanup {{{
cleanup()
-- }}}