Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / puzzle.c
1
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <WINGs.h>
5
6 #define MAX_SIZE 10*10
7
8 WMWindow *win;
9 WMButton *Button[MAX_SIZE];
10 char Map[MAX_SIZE];
11 int Size = 4;
12 int MoveCount;
13
14 #define MAP(x,y) Map[(x)+(y)*Size]
15
16 int WinSize = 120;
17
18 Bool CheckWin(void)
19 {
20 int i;
21
22 for (i = 0; i < Size * Size - 1; i++) {
23 if (Map[i] != i)
24 return False;
25 }
26
27 return True;
28 }
29
30 void MoveButton(int button, int x, int y)
31 {
32 WMMoveWidget(Button[button], x * (WinSize / Size), y * (WinSize / Size));
33 }
34
35 Bool SlideButton(int button)
36 {
37 int x, y, done = 0;
38
39 /* locate the button */
40 for (y = 0; y < Size; y++) {
41 for (x = 0; x < Size; x++) {
42 if (MAP(x, y) == button) {
43 done = 1;
44 break;
45 }
46 }
47 if (done)
48 break;
49 }
50
51 if (x > 0 && MAP(x - 1, y) < 0) {
52 MAP(x, y) = -1;
53 MoveButton(button, x - 1, y);
54 MAP(x - 1, y) = button;
55 } else if (x < Size - 1 && MAP(x + 1, y) < 0) {
56 MAP(x, y) = -1;
57 MoveButton(button, x + 1, y);
58 MAP(x + 1, y) = button;
59 } else if (y > 0 && MAP(x, y - 1) < 0) {
60 MAP(x, y) = -1;
61 MoveButton(button, x, y - 1);
62 MAP(x, y - 1) = button;
63 } else if (y < Size - 1 && MAP(x, y + 1) < 0) {
64 MAP(x, y) = -1;
65 MoveButton(button, x, y + 1);
66 MAP(x, y + 1) = button;
67 } else {
68 return False;
69 }
70 return True;
71 }
72
73 #define SWAP(a,b) {int tmp; tmp=a; a=b; b=tmp;}
74
75 void ResetGame(void)
76 {
77 int i, x, y, ox, oy;
78
79 MoveCount = 0;
80
81 for (i = 0; i < Size * Size - 1; i++) {
82 Map[i] = i;
83 }
84 Map[i] = -1;
85 ox = x = Size - 1;
86 oy = y = Size - 1;
87 for (i = 0; i < 5; i++) {
88 int ok;
89 ok = 1;
90 switch (rand() % 4) {
91 case 0:
92 if (x > 0)
93 x--;
94 else
95 ok = 0;
96 break;
97 case 2:
98 if (x < Size - 1)
99 x++;
100 else
101 ok = 0;
102 break;
103 case 1:
104 if (y > 0)
105 y--;
106 else
107 ok = 0;
108 break;
109 case 3:
110 if (y < Size - 1)
111 y++;
112 else
113 ok = 0;
114 break;
115 }
116 if (ok) {
117 MoveButton(MAP(x, y), ox, oy);
118
119 SWAP(MAP(ox, oy), MAP(x, y));
120
121 while (XPending(WMScreenDisplay(WMWidgetScreen(win)))) {
122 XEvent ev;
123 WMNextEvent(WMScreenDisplay(WMWidgetScreen(win)), &ev);
124 WMHandleEvent(&ev);
125 }
126 ox = x;
127 oy = y;
128 }
129 }
130 }
131
132 void buttonClick(WMWidget * w, void *ptr)
133 {
134 char buffer[300];
135
136 if (SlideButton((int)ptr)) {
137 MoveCount++;
138
139 if (CheckWin()) {
140 sprintf(buffer, "You finished the game in %i moves.", MoveCount);
141
142 if (WMRunAlertPanel(WMWidgetScreen(w), win, "You Won!", buffer,
143 "Wee!", "Gah! Lemme retry!", NULL) == WAPRDefault) {
144 exit(0);
145 }
146
147 ResetGame();
148 }
149 }
150 }
151
152 static void resizeObserver(void *self, WMNotification * notif)
153 {
154 WMSize size = WMGetViewSize(WMWidgetView(win));
155 int x, y;
156
157 WinSize = size.width;
158 for (y = 0; y < Size; y++) {
159 for (x = 0; x < Size; x++) {
160 if (MAP(x, y) >= 0) {
161 WMResizeWidget(Button[(int)MAP(x, y)], WinSize / Size, WinSize / Size);
162 WMMoveWidget(Button[(int)MAP(x, y)], x * (WinSize / Size), y * (WinSize / Size));
163 }
164 }
165 }
166
167 }
168
169 int main(int argc, char **argv)
170 {
171 Display *dpy;
172 WMScreen *scr;
173 int x, y, i;
174
175 WMInitializeApplication("Puzzle", &argc, argv);
176
177 dpy = XOpenDisplay("");
178 if (!dpy) {
179 printf("could not open display\n");
180 exit(1);
181 }
182
183 scr = WMCreateScreen(dpy, DefaultScreen(dpy));
184
185 win = WMCreateWindow(scr, "puzzle");
186 WMResizeWidget(win, WinSize, WinSize);
187 WMSetWindowTitle(win, "zuPzel");
188 WMSetWindowMinSize(win, 80, 80);
189 WMSetWindowAspectRatio(win, 2, 2, 2, 2);
190 WMSetWindowResizeIncrements(win, Size, Size);
191 WMSetViewNotifySizeChanges(WMWidgetView(win), True);
192 WMAddNotificationObserver(resizeObserver, NULL, WMViewSizeDidChangeNotification, WMWidgetView(win));
193
194 for (i = y = 0; y < Size && i < Size * Size - 1; y++) {
195 for (x = 0; x < Size && i < Size * Size - 1; x++) {
196 char buf[32];
197 WMColor *color;
198 RColor col;
199 RHSVColor hsv;
200
201 hsv.hue = i * 360 / (Size * Size - 1);
202 hsv.saturation = 120;
203 hsv.value = 200;
204
205 RHSVtoRGB(&hsv, &col);
206
207 color = WMCreateRGBColor(scr, col.red << 8, col.green << 8, col.blue << 8, False);
208
209 MAP(x, y) = i;
210 Button[i] = WMCreateButton(win, WBTMomentaryLight);
211 WMSetWidgetBackgroundColor(Button[i], color);
212 WMReleaseColor(color);
213 WMSetButtonAction(Button[i], buttonClick, (void *)i);
214 WMResizeWidget(Button[i], WinSize / Size, WinSize / Size);
215 WMMoveWidget(Button[i], x * (WinSize / Size), y * (WinSize / Size));
216 sprintf(buf, "%i", i + 1);
217 WMSetButtonText(Button[i], buf);
218 WMSetButtonTextAlignment(Button[i], WACenter);
219 i++;
220 }
221 }
222
223 WMMapSubwidgets(win);
224 WMMapWidget(win);
225 WMRealizeWidget(win);
226
227 ResetGame();
228
229 WMScreenMainLoop(scr);
230
231 return 0;
232 }