21e69104f481407e8acbf7029489e3dd40bd2220
[wmaker-crm.git] / WINGs / Examples / puzzle.c
blob21e69104f481407e8acbf7029489e3dd40bd2220
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <WINGs/WINGs.h>
7 #include <stdint.h>
10 #define MAX_SIZE 10*10
13 WMWindow *win;
14 WMButton *Button[MAX_SIZE];
15 char Map[MAX_SIZE];
16 int Size = 4;
17 int MoveCount;
19 #define MAP(x,y) Map[(x)+(y)*Size]
21 int WinSize = 120;
24 Bool
25 CheckWin(void)
27 int i;
29 for (i = 0; i < Size*Size-1; i++) {
30 if (Map[i] != i)
31 return False;
34 return True;
38 void
39 MoveButton(int button, int x, int y)
41 WMMoveWidget(Button[button], x*(WinSize/Size), y*(WinSize/Size));
45 Bool
46 SlideButton(int button)
48 int x=0, y=0, done = 0;
50 /* locate the button */
51 for (y = 0; y < Size; y++) {
52 for (x = 0; x < Size; x++) {
53 if (MAP(x,y) == button) {
54 done = 1;
55 break;
58 if (done)
59 break;
62 if (x > 0 && MAP(x-1, y) < 0) {
63 MAP(x,y) = -1;
64 MoveButton(button, x-1, y);
65 MAP(x-1,y) = button;
66 } else if (x < Size-1 && MAP(x+1, y) < 0) {
67 MAP(x,y) = -1;
68 MoveButton(button, x+1, y);
69 MAP(x+1,y) = button;
70 } else if (y > 0 && MAP(x, y-1) < 0) {
71 MAP(x,y) = -1;
72 MoveButton(button, x, y-1);
73 MAP(x,y-1) = button;
74 } else if (y < Size-1 && MAP(x, y+1) < 0) {
75 MAP(x,y) = -1;
76 MoveButton(button, x, y+1);
77 MAP(x,y+1) = button;
78 } else {
79 return False;
81 return True;
85 #define SWAP(a,b) {int tmp; tmp=a; a=b; b=tmp;}
87 void ResetGame(void)
89 int i, x, y, ox, oy;
92 MoveCount = 0;
94 for (i = 0; i < Size*Size-1; i++) {
95 Map[i] = i;
97 Map[i] = -1;
98 ox = x = Size-1;
99 oy = y = Size-1;
100 for (i = 0; i < 1000; i++) {
101 int ok;
102 ok = 1;
103 switch (rand()%4) {
104 case 0:
105 if (x > 0) x--; else ok = 0;
106 break;
107 case 2:
108 if (x < Size-1) x++; else ok = 0;
109 break;
110 case 1:
111 if (y > 0) y--; else ok = 0;
112 break;
113 case 3:
114 if (y < Size-1) y++; else ok = 0;
115 break;
117 if (ok) {
118 MoveButton(MAP(x,y), ox, oy);
120 SWAP(MAP(ox, oy), MAP(x, y));
122 while (XPending(WMScreenDisplay(WMWidgetScreen(win)))) {
123 XEvent ev;
124 WMNextEvent(WMScreenDisplay(WMWidgetScreen(win)), &ev);
125 WMHandleEvent(&ev);
127 ox = x;
128 oy = y;
134 void buttonClick(WMWidget *w, void *ptr)
136 char buffer[300];
138 if (SlideButton((int)(uintptr_t)ptr)) {
139 MoveCount++;
141 if (CheckWin()) {
142 sprintf(buffer, "You finished the game in %i moves.", MoveCount);
144 if (WMRunAlertPanel(WMWidgetScreen(w), win, "You Won!", buffer,
145 "Wee!", "Gah! Lemme retry!", NULL) == WAPRDefault) {
146 exit(0);
149 ResetGame();
155 static void resizeObserver(void *self, WMNotification *notif)
157 WMSize size = WMGetViewSize(WMWidgetView(win));
158 int x, y;
160 WinSize = size.width;
161 for (y = 0; y < Size; y++) {
162 for (x = 0; x < Size; x++) {
163 if (MAP(x,y) >= 0) {
164 WMResizeWidget(Button[(int)MAP(x,y)],
165 WinSize/Size, WinSize/Size);
166 WMMoveWidget(Button[(int)MAP(x,y)],
167 x*(WinSize/Size), y*(WinSize/Size));
175 int main(int argc, char **argv)
177 Display *dpy;
178 WMScreen *scr;
179 int x, y, i;
181 WMInitializeApplication("Puzzle", &argc, argv);
184 dpy = XOpenDisplay("");
185 if (!dpy) {
186 printf("could not open display\n");
187 exit(1);
190 scr = WMCreateScreen(dpy, DefaultScreen(dpy));
192 win = WMCreateWindow(scr, "puzzle");
193 WMResizeWidget(win, WinSize, WinSize);
194 WMSetWindowTitle(win, "zuPzel");
195 WMSetWindowMinSize(win, 80, 80);
196 WMSetWindowAspectRatio(win, 2, 2, 2, 2);
197 WMSetWindowResizeIncrements(win, Size, Size);
198 WMSetViewNotifySizeChanges(WMWidgetView(win), True);
199 WMAddNotificationObserver(resizeObserver, NULL,
200 WMViewSizeDidChangeNotification,
201 WMWidgetView(win));
205 for (i = y = 0; y < Size && i < Size*Size-1; y++) {
206 for (x = 0; x < Size && i < Size*Size-1; x++) {
207 char buf[32];
208 WMColor *color;
209 RColor col;
210 RHSVColor hsv;
212 hsv.hue = i*360/(Size*Size-1);
213 hsv.saturation = 120;
214 hsv.value = 200;
216 RHSVtoRGB(&hsv, &col);
218 color = WMCreateRGBColor(scr, col.red<<8, col.green<<8,
219 col.blue<<8, False);
221 MAP(x,y) = i;
222 Button[i] = WMCreateButton(win, WBTMomentaryLight);
223 WMSetWidgetBackgroundColor(Button[i], color);
224 WMReleaseColor(color);
225 WMSetButtonAction(Button[i], buttonClick, (void*)(uintptr_t)i);
226 WMResizeWidget(Button[i], WinSize/Size, WinSize/Size);
227 WMMoveWidget(Button[i], x*(WinSize/Size), y*(WinSize/Size));
228 sprintf(buf, "%i", i+1);
229 WMSetButtonText(Button[i], buf);
230 WMSetButtonTextAlignment(Button[i], WACenter);
231 i++;
235 WMMapSubwidgets(win);
236 WMMapWidget(win);
237 WMRealizeWidget(win);
239 ResetGame();
241 WMScreenMainLoop(scr);
243 return 0;