xref: /plan9/sys/src/games/mahjongg/logic.c (revision 8fd921c82c91d57a22d5e5497ed27daf3ec44f36)
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <event.h>
5 
6 #include "mahjongg.h"
7 
8 Click NC = { -1, 0, 0, };
9 
10 Click
Cl(int d,int x,int y)11 Cl(int d, int x, int y)
12 {
13 	return (Click){d, x, y};
14 }
15 
16 int
eqcl(Click c1,Click c2)17 eqcl(Click c1, Click c2)
18 {
19 	return c1.d == c2.d && c1.x == c2.x && c1.y == c2.y;
20 }
21 
22 int
freeup(Click c)23 freeup(Click c)
24 {
25 	if(c.d == Depth -1 || (level.board[c.d+1][c.x][c.y].which == None &&
26 	    level.board[c.d+1][c.x+1][c.y].which == None &&
27 	    level.board[c.d+1][c.x][c.y+1].which == None &&
28 	    level.board[c.d+1][c.x+1][c.y+1].which == None))
29 		return 1;
30 	return 0;
31 }
32 
33 int
freeleft(Click c)34 freeleft(Click c)
35 {
36 	if(c.x == 0 || (level.board[c.d][c.x-1][c.y].which == None &&
37 	    level.board[c.d][c.x-1][c.y+1].which == None))
38 		return 1;
39 	return 0;
40 }
41 
42 int
freeright(Click c)43 freeright(Click c)
44 {
45 	if(c.x == Lx-2 || (level.board[c.d][c.x+2][c.y].which == None &&
46 	    level.board[c.d][c.x+2][c.y+1].which == None))
47 		return 1;
48 	return 0;
49 }
50 
51 int
isfree(Click c)52 isfree(Click c)
53 {
54 	return (freeleft(c) || freeright(c)) && freeup(c);
55 }
56 
57 Click
cmatch(Click c,int dtop)58 cmatch(Click c, int dtop)
59 {
60 	Click lc;
61 
62 	lc.d = dtop;
63 	do {
64 		for(lc.y = 0; lc.y < Ly; lc.y++)
65 			for(lc.x = 0; lc.x < Lx; lc.x++)
66 				if(level.board[lc.d][lc.x][lc.y].which == TL &&
67 				    isfree(lc) && !eqcl(c, lc) &&
68 				    level.board[c.d][c.x][c.y].type ==
69 				    level.board[lc.d][lc.x][lc.y].type)
70 					return lc;
71 	} while(--lc.d >= 0);
72 	return NC;
73 }
74 
75 Brick *
bmatch(Click c)76 bmatch(Click c)
77 {
78 	Click lc;
79 
80 	lc = cmatch(c, Depth);
81 	if(lc.d == -1)
82 		return nil;
83 	else
84 		return &level.board[lc.d][lc.x][lc.y];
85 }
86 
87 int
canmove(void)88 canmove(void)
89 {
90 	Click c;
91 
92 	for(c.d = Depth - 1; c.d >= 0; c.d--)
93 		for(c.y = 0; c.y < Ly; c.y++)
94 			for(c.x = 0; c.x < Lx; c.x++)
95 				if(level.board[c.d][c.x][c.y].which == TL &&
96 				    isfree(c) && bmatch(c) != nil)
97 					return 1;
98 	return 0;
99 }
100