-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmaps.lua
158 lines (137 loc) · 4.28 KB
/
maps.lua
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
--[[
This file contain what is needed to generate the map or read it from
a text file and to display it.
]]
--[[the map is represeted as a 2 dimention array
The possible elements are :
void : a case not in the arena, no fruits can go there
ground : nothing on the case
wall : a wall on the case
head : the head of the snek
body : the body of the snek
fruit : the fruits the snek can eat
Each element got an ID, a color palette and a representing character
]]
--[[
Deyond the tiles a map contain a reference to a snek on the map and a
number, max, wich represent the max size the snake can grow
]]
--definitions
void = {id = 0, color = 1, char = " "}
ground = {id = 1, color = 1, char = " "}
wall = {id = 2, color = 2, char = " "}
head = {id = 3, color = 3, char = "@"}
body = {id = 4, color = 3, char = "+"}
fruit = {id = 5, color = 4, char = "o"}
--generate the most boring map you can think of
function rectangleMap(snek, fruits, y, x)
local ret = map(snek, fruits)
for i=1,y do
ret[i] = {}
for j=1,x do
if i==1 or j==1 or j==x or i==y then
ret[i][j] = wall
else
ret[i][j] = ground
end
end
end
ret:setMaxGnd()
return ret
end
--a basic map class
function map(snek, fruits)
local ret = {["snek"] = snek, ["max"] = 0, ["fruits"] = fruits, ["waitingFruits"] = false}
--put the maximum number of fruits in the map
ret.fillFruits = function(map)
for i=1,map.fruits do
map:addFruit()
end
if map:cmpTiles(fruit) >= map.fruits then
map.waitingFruits = false
end
end
--refresh the screen
ret.show = function(map)
map:drawMap()
map.snek:show()
nc.refresh()
end
--return weather or not the head of the snek is on a fruit and if true hange the case back to normal ground
ret.yum = function(map)
if map[map.snek.head.y][map.snek.head.x] == fruit then
map[map.snek.head.y][map.snek.head.x] = ground
return true
else
return false
end
end
--draw a map a tad to the top left of the terminal
ret.drawMap = function(map)
for i=1,#map do
nc.move(i+offset-1, offset)
for j=1,#map[i] do
local case = map[i][j]
nc.set_color(case.color)
nc.printw(case.char)
end
end
end
--chack if the snek in the map is bumping it's head against a wall
ret.isBumping = function(map)
return map[map.snek.head.y][map.snek.head.x] == wall
end
--change a ground case not bellow the snek in a fruit case
ret.addFruit = function(map)
if map:cmpTiles(fruit) < map.fruits then
local groundMap = map:freeGround()
if #groundMap > 0 then
local i = math.random(1, #groundMap)
map[groundMap[i].y][groundMap[i].x] = fruit
else
if map:cmpTiles(fruit) == 0 then
map.waitingFruits = true --if we need more fruits but we cant place it we should note it
end
end
end
end
--put the number of ground tiles in the max fied
ret.setMaxGnd = function(map)
map.max = map:cmpGround()
end
--return the number of ground tiles
ret.cmpGround = function(map)
return map:cmpTiles(ground)
end
--return the number of a given tile
ret.cmpTiles = function(map, tile)
local ret = 0
for i=1,#map do
for j=1,#map[i] do
if map[i][j] == tile then
ret = ret + 1
end
end
end
return ret
end
--return a list of free ground tiles
ret.freeGround = function(map)
local ret = {}
for i=1,#map do
for j=1,#map[i] do
if map[i][j] == ground then
if not map.snek:isSnek(pos(i, j)) then
ret[#ret+1] = pos(i,j)
end
end
end
end
return ret
end
--return true if the size of the snake is equal to the max field
ret.isWin = function(map)
return (#map.snek.body + 1) >= map.max
end
return ret
end