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