1a7b22450SDavid du Colombier #include <u.h>
2a7b22450SDavid du Colombier #include <libc.h>
3a7b22450SDavid du Colombier #include <bio.h>
4a7b22450SDavid du Colombier #include <draw.h>
5a7b22450SDavid du Colombier
6a7b22450SDavid du Colombier #include "mahjongg.h"
7a7b22450SDavid du Colombier
8a7b22450SDavid du Colombier void
consumeline(Biobuf * b)9a7b22450SDavid du Colombier consumeline(Biobuf *b)
10a7b22450SDavid du Colombier {
11a7b22450SDavid du Colombier while(Bgetc(b) != '\n')
12a7b22450SDavid du Colombier ;
13a7b22450SDavid du Colombier }
14a7b22450SDavid du Colombier
15a7b22450SDavid du Colombier /* parse a level file */
16a7b22450SDavid du Colombier int
parse(char * layout)17a7b22450SDavid du Colombier parse(char *layout)
18a7b22450SDavid du Colombier {
19a7b22450SDavid du Colombier int x = 0, y = 0, depth = 0;
20a7b22450SDavid du Colombier char c;
21*8fd921c8SDavid du Colombier Biobuf *b;
22a7b22450SDavid du Colombier
23a7b22450SDavid du Colombier b = Bopen(layout, OREAD);
24a7b22450SDavid du Colombier if(b == nil) {
25a7b22450SDavid du Colombier fprint(2, "could not open file %s: %r\n", layout);
26a7b22450SDavid du Colombier return 0;
27a7b22450SDavid du Colombier }
28a7b22450SDavid du Colombier
29a7b22450SDavid du Colombier level.remaining = 0;
30a7b22450SDavid du Colombier
31a7b22450SDavid du Colombier while((c = Bgetc(b)) > 0) {
32a7b22450SDavid du Colombier switch(c) {
33a7b22450SDavid du Colombier case '\n':
34a7b22450SDavid du Colombier x = 0;
35a7b22450SDavid du Colombier y = (y+1) % Ly;
36a7b22450SDavid du Colombier if(!y)
37a7b22450SDavid du Colombier depth++;
38a7b22450SDavid du Colombier break;
39a7b22450SDavid du Colombier case '.':
40a7b22450SDavid du Colombier orig.board[depth][x][y].which = 0;
41a7b22450SDavid du Colombier x++;
42a7b22450SDavid du Colombier break;
43a7b22450SDavid du Colombier case '1':
44a7b22450SDavid du Colombier orig.remaining++;
45a7b22450SDavid du Colombier case '2':
46a7b22450SDavid du Colombier case '3':
47a7b22450SDavid du Colombier case '4':
48a7b22450SDavid du Colombier orig.board[depth][x++][y].which = c-48;
49a7b22450SDavid du Colombier break;
50a7b22450SDavid du Colombier default:
51a7b22450SDavid du Colombier consumeline(b);
52a7b22450SDavid du Colombier break;
53a7b22450SDavid du Colombier }
54a7b22450SDavid du Colombier }
55a7b22450SDavid du Colombier Bterm(b);
56a7b22450SDavid du Colombier
57a7b22450SDavid du Colombier return 1;
58a7b22450SDavid du Colombier }
59a7b22450SDavid du Colombier
60a7b22450SDavid du Colombier int
indextype(int type)61a7b22450SDavid du Colombier indextype(int type)
62a7b22450SDavid du Colombier {
63a7b22450SDavid du Colombier int t;
64a7b22450SDavid du Colombier
65a7b22450SDavid du Colombier if(type < 108)
66a7b22450SDavid du Colombier t = (type/36)*Facey * 9 + ((type%36)/4)*Facex;
67a7b22450SDavid du Colombier else if(type < 112)
68a7b22450SDavid du Colombier t = Seasons;
69a7b22450SDavid du Colombier else if(type < 128)
70a7b22450SDavid du Colombier t = 3*Facey + (((type+12)%36)/4)*Facex;
71a7b22450SDavid du Colombier else if(type < 132)
72a7b22450SDavid du Colombier t = Flowers;
73a7b22450SDavid du Colombier else
74a7b22450SDavid du Colombier t = 4*Facey + (((type+28)%36)/4)*Facex;
75a7b22450SDavid du Colombier
76a7b22450SDavid du Colombier return t;
77a7b22450SDavid du Colombier
78a7b22450SDavid du Colombier }
79a7b22450SDavid du Colombier
80a7b22450SDavid du Colombier Point
indexpt(int type)81a7b22450SDavid du Colombier indexpt(int type)
82a7b22450SDavid du Colombier {
83a7b22450SDavid du Colombier Point p;
84a7b22450SDavid du Colombier
85*8fd921c8SDavid du Colombier /*
86*8fd921c8SDavid du Colombier * the first 108 bricks are 4 of each, 36 per line:
87a7b22450SDavid du Colombier * x = (index%36)/4
88a7b22450SDavid du Colombier * y = (index)/36
89a7b22450SDavid du Colombier * then multiply by the size of a single tile.
90a7b22450SDavid du Colombier * the next 4 are the seasons, so x = index%4...
91a7b22450SDavid du Colombier * and so on...
92a7b22450SDavid du Colombier */
93a7b22450SDavid du Colombier
94*8fd921c8SDavid du Colombier if(type < 108)
95a7b22450SDavid du Colombier p = Pt(((type%36)/4)*Facex, (type/36)*Facey);
96*8fd921c8SDavid du Colombier else if(type < 112)
97a7b22450SDavid du Colombier p = Pt((type%4)*Facex, 3*Facey);
98*8fd921c8SDavid du Colombier else if(type < 128)
99a7b22450SDavid du Colombier p = Pt((((type+12)%36)/4)*Facex, 3*Facey);
100*8fd921c8SDavid du Colombier else if(type < 132)
101a7b22450SDavid du Colombier p = Pt(((type+4)%4)*Facex, 4*Facey);
102*8fd921c8SDavid du Colombier else
103a7b22450SDavid du Colombier p = Pt((((type+28)%36)/4)*Facex, 4*Facey);
104a7b22450SDavid du Colombier return p;
105a7b22450SDavid du Colombier }
106a7b22450SDavid du Colombier
107a7b22450SDavid du Colombier /* use the seed to generate a replayable game */
108a7b22450SDavid du Colombier void
generate(uint seed)109a7b22450SDavid du Colombier generate(uint seed)
110a7b22450SDavid du Colombier {
111a7b22450SDavid du Colombier int x, y, d, n;
112a7b22450SDavid du Colombier int order[144];
113*8fd921c8SDavid du Colombier Point p;
114a7b22450SDavid du Colombier
115a7b22450SDavid du Colombier srand(seed);
116a7b22450SDavid du Colombier
117a7b22450SDavid du Colombier for (x = 0; x < Tiles; x++)
118a7b22450SDavid du Colombier order[x] = x;
119a7b22450SDavid du Colombier
120a7b22450SDavid du Colombier for(x = 0; x < Tiles; x++) {
121a7b22450SDavid du Colombier n = order[x];
122a7b22450SDavid du Colombier y = nrand(Tiles);
123a7b22450SDavid du Colombier order[x] = order[y];
124a7b22450SDavid du Colombier order[y] = n;
125a7b22450SDavid du Colombier }
126a7b22450SDavid du Colombier
127a7b22450SDavid du Colombier n = 0;
128a7b22450SDavid du Colombier for(d = 0; d < Depth; d++)
129a7b22450SDavid du Colombier for(y = 0; y < Ly; y++)
130a7b22450SDavid du Colombier for(x = 0; x < Lx; x++)
131a7b22450SDavid du Colombier if(orig.board[d][x][y].which == 1) {
132a7b22450SDavid du Colombier
133a7b22450SDavid du Colombier orig.board[d][x][y].type = indextype(order[n]);
134a7b22450SDavid du Colombier p = indexpt(order[n++]);
135a7b22450SDavid du Colombier orig.board[d][x][y].start = p;
136a7b22450SDavid du Colombier orig.board[d][x+1][y].start = p;
137a7b22450SDavid du Colombier orig.board[d][x][y+1].start = p;
138a7b22450SDavid du Colombier orig.board[d][x+1][y+1].start = p;
139a7b22450SDavid du Colombier }
140a7b22450SDavid du Colombier
141a7b22450SDavid du Colombier if(n != orig.remaining)
142*8fd921c8SDavid du Colombier fprint(2, "level improperly generated: %d elements, "
143*8fd921c8SDavid du Colombier "should have %d\n", n, orig.remaining);
144a7b22450SDavid du Colombier
145*8fd921c8SDavid du Colombier orig.c = NC;
146*8fd921c8SDavid du Colombier orig.l = NC;
147a7b22450SDavid du Colombier orig.done = 0;
148a7b22450SDavid du Colombier level = orig;
149a7b22450SDavid du Colombier }
150