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