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 }