Fix periodic focus bug
[wmaker-crm.git] / WINGs / puzzle.c
blob6f9b6caee53b22cf4150ce9c0774c7259907d35f
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <WINGs.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 CheckWin(void)
26 int i;
28 for (i = 0; i < Size*Size-1; i++) {
29 if (Map[i] != i)
30 return False;
33 return True;
37 void MoveButton(int button, int x, int y)
39 WMMoveWidget(Button[button], x*(WinSize/Size), y*(WinSize/Size));
43 Bool SlideButton(int button)
45 int x, y, done = 0;
47 /* locate the button */
48 for (y = 0; y < Size; y++) {
49 for (x = 0; x < Size; x++) {
50 if (MAP(x,y) == button) {
51 done = 1;
52 break;
55 if (done)
56 break;
59 if (x > 0 && MAP(x-1, y) < 0) {
60 MAP(x,y) = -1;
61 MoveButton(button, x-1, y);
62 MAP(x-1,y) = button;
63 } else if (x < Size-1 && MAP(x+1, y) < 0) {
64 MAP(x,y) = -1;
65 MoveButton(button, x+1, y);
66 MAP(x+1,y) = button;
67 } else if (y > 0 && MAP(x, y-1) < 0) {
68 MAP(x,y) = -1;
69 MoveButton(button, x, y-1);
70 MAP(x,y-1) = button;
71 } else if (y < Size-1 && MAP(x, y+1) < 0) {
72 MAP(x,y) = -1;
73 MoveButton(button, x, y+1);
74 MAP(x,y+1) = button;
75 } else {
76 return False;
78 return True;
82 #define SWAP(a,b) {int tmp; tmp=a; a=b; b=tmp;}
84 void ResetGame(void)
86 int i, x, y, ox, oy;
89 MoveCount = 0;
91 for (i = 0; i < Size*Size-1; i++) {
92 Map[i] = i;
94 Map[i] = -1;
95 ox = x = Size-1;
96 oy = y = Size-1;
97 for (i = 0; i < 5; i++) {
98 int ok;
99 ok = 1;
100 switch (rand()%4) {
101 case 0:
102 if (x > 0) x--; else ok = 0;
103 break;
104 case 2:
105 if (x < Size-1) x++; else ok = 0;
106 break;
107 case 1:
108 if (y > 0) y--; else ok = 0;
109 break;
110 case 3:
111 if (y < Size-1) y++; else ok = 0;
112 break;
114 if (ok) {
115 MoveButton(MAP(x,y), ox, oy);
117 SWAP(MAP(ox, oy), MAP(x, y));
119 while (XPending(WMScreenDisplay(WMWidgetScreen(win)))) {
120 XEvent ev;
121 WMNextEvent(WMScreenDisplay(WMWidgetScreen(win)), &ev);
122 WMHandleEvent(&ev);
124 ox = x;
125 oy = y;
131 void buttonClick(WMWidget *w, void *ptr)
133 char buffer[300];
135 if (SlideButton((int)ptr)) {
136 MoveCount++;
138 if (CheckWin()) {
139 sprintf(buffer, "You finished the game in %i moves.", MoveCount);
141 if (WMRunAlertPanel(WMWidgetScreen(w), win, "You Won!", buffer,
142 "Wee!", "Gah! Lemme retry!", NULL) == WAPRDefault) {
143 exit(0);
146 ResetGame();
152 static void resizeObserver(void *self, WMNotification *notif)
154 WMSize size = WMGetViewSize(WMWidgetView(win));
155 int x, y;
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)],
162 WinSize/Size, WinSize/Size);
163 WMMoveWidget(Button[(int)MAP(x,y)],
164 x*(WinSize/Size), y*(WinSize/Size));
172 int main(int argc, char **argv)
174 Display *dpy;
175 WMScreen *scr;
176 int x, y, i;
178 WMInitializeApplication("Puzzle", &argc, argv);
181 dpy = XOpenDisplay("");
182 if (!dpy) {
183 printf("could not open display\n");
184 exit(1);
187 scr = WMCreateScreen(dpy, DefaultScreen(dpy));
189 win = WMCreateWindow(scr, "puzzle");
190 WMResizeWidget(win, WinSize, WinSize);
191 WMSetWindowTitle(win, "zuPzel");
192 WMSetWindowMinSize(win, 80, 80);
193 WMSetWindowAspectRatio(win, 2, 2, 2, 2);
194 WMSetWindowResizeIncrements(win, Size, Size);
195 WMSetViewNotifySizeChanges(WMWidgetView(win), True);
196 WMAddNotificationObserver(resizeObserver, NULL,
197 WMViewSizeDidChangeNotification,
198 WMWidgetView(win));
202 for (i = y = 0; y < Size && i < Size*Size-1; y++) {
203 for (x = 0; x < Size && i < Size*Size-1; x++) {
204 char buf[32];
205 WMColor *color;
206 RColor col;
207 RHSVColor hsv;
209 hsv.hue = i*360/(Size*Size-1);
210 hsv.saturation = 120;
211 hsv.value = 200;
213 RHSVtoRGB(&hsv, &col);
215 color = WMCreateRGBColor(scr, col.red<<8, col.green<<8,
216 col.blue<<8, False);
218 MAP(x,y) = i;
219 Button[i] = WMCreateButton(win, WBTMomentaryLight);
220 WMSetWidgetBackgroundColor(Button[i], color);
221 WMReleaseColor(color);
222 WMSetButtonAction(Button[i], buttonClick, (void*)i);
223 WMResizeWidget(Button[i], WinSize/Size, WinSize/Size);
224 WMMoveWidget(Button[i], x*(WinSize/Size), y*(WinSize/Size));
225 sprintf(buf, "%i", i+1);
226 WMSetButtonText(Button[i], buf);
227 WMSetButtonTextAlignment(Button[i], WACenter);
228 i++;
232 WMMapSubwidgets(win);
233 WMMapWidget(win);
234 WMRealizeWidget(win);
236 ResetGame();
238 WMScreenMainLoop(scr);
240 return 0;