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
|
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <draw.h>
#include "sokoban.h"
void
consumeline(Biobuf *b)
{
while(Bgetc(b) != '\n')
;
}
/* parse a level file */
int
loadlevels(char *path)
{
Biobuf *b;
int x = 0, y = 0, lnum = 0;
char c;
if(path == nil)
return 0;
b = Bopen(path, OREAD);
if(b == nil) {
fprint(2, "could not open file %s: %r\n", path);
return 0;
}
memset(levels, 0, Maxlevels*sizeof(Level));
while((c = Bgetc(b)) > 0) {
switch(c) {
case ';':
consumeline(b); /* no ';'-comments in the middle of a level */
break;
case '\n':
levels[lnum].index = lnum;
levels[lnum].done = 0;
x = 0;
levels[lnum].max.y = ++y;
c = Bgetc(b);
if(c == '\n' || c == Beof) {
/* end of level */
if(++lnum == Maxlevels)
goto Done;
x = 0;
y = 0;
} else
Bungetc(b);
break;
case '#':
levels[lnum].board[x][y] = Wall;
x++;
break;
case ' ':
levels[lnum].board[x][y] = Empty;
x++;
break;
case '$':
levels[lnum].board[x][y] = Cargo;
x++;
break;
case '*':
levels[lnum].board[x][y] = GoalCargo;
x++;
break;
case '.':
levels[lnum].board[x][y] = Goal;
x++;
break;
case '@':
levels[lnum].board[x][y] = Empty;
levels[lnum].glenda = Pt(x, y);
x++;
break;
case '+':
levels[lnum].board[x][y] = Goal;
levels[lnum].glenda = Pt(x, y);
x++;
break;
default:
fprint(2, "impossible character for level %d: %c\n", lnum+1, c);
return 0;
}
if(x > levels[lnum].max.x)
levels[lnum].max.x = x;
levels[lnum].max.y = y;
}
Done:
Bterm(b);
level = levels[0];
numlevels = lnum;
return 1;
}
|