#include #include #include "smaze.h" #define CellWidth ((Width-HGrids-1)/HGrids) #define CellHeight ((Height-VGrids-1)/VGrids) #define CellX(i) ((i)*(Width-HGrids-1)/HGrids+(i)+1) #define CellY(j) ((j)*(Height-VGrids-1)/VGrids+(j)+1) extern Agent A; extern char World[VGrids][HGrids]; #define NGRAYSCALE 32 static int NGrayScale = NGRAYSCALE; static unsigned long pixel[NGRAYSCALE]; extern Display *dpy; GC gc; static Window window; static Pixmap backmap; static unsigned int Width, Height; extern unsigned long fg, bg; extern XFontStruct *stepFont; draw_init(win) Window win; { Window root; int scr = DefaultScreen(dpy), x, y, i; unsigned int b, d, pl[1]; Colormap cmap = DefaultColormap(dpy,scr); XColor scol; XGetGeometry(dpy,win,&root,&x,&y,&Width,&Height,&b,&d); window = win; backmap = XCreatePixmap(dpy,win,Width,Height,d); gc = DefaultGC(dpy,scr); while (NGrayScale >= 8 && !XAllocColorCells(dpy,cmap,False,pl,1,pixel,NGrayScale)) NGrayScale --; if (NGrayScale < 8) { perror("There is no room to allocate enough color cells."); exit(1); } scol.flags = DoRed | DoGreen | DoBlue; for (b = 0; b < NGrayScale; b++) { scol.pixel = pixel[b]; scol.red = scol.green = scol.blue = b * 65535 / (NGrayScale-1); XStoreColor(dpy,cmap,&scol); } } redisplay(e) XExposeEvent *e; { XCopyArea(dpy,backmap,window,gc, e->x,e->y,e->width,e->height,e->x,e->y); } check_input(e) XButtonEvent *e; { if (e->type != ButtonRelease) return 0; pointer_proc(e->x * HGrids / Width, e->y * VGrids / Height, e->button); } display_switch(flag) int flag; { if (flag) draw_view(0); else { XSetForeground(dpy,gc,fg); XDrawLine(dpy,backmap,gc,0,0,Width-1,Height-1); XDrawLine(dpy,backmap,gc,0,Height-1,Width-1,0); XCopyArea(dpy,backmap,window,gc,0,0,Width,Height,0,0); } } static void draw_qvalue1(x,y,w,h,min,max,q) int x,y,w,h; double min,max,q; { int i = (q-min) / (max-min) * NGrayScale; if (i >= NGrayScale) i = NGrayScale - 1; XSetForeground(dpy,gc,pixel[NGrayScale - i - 1]); XFillRectangle(dpy,backmap,gc,x,y,w,h); } static void draw_qvalue(i,j,q) int i,j; double q[]; { int x = i * Width / HGrids, y = j * Height / VGrids, w = Width / HGrids, h = Height / VGrids; double max, min; /* max = min = q[0]; for (i = 1; i < NActions; i ++) { if (max < q[i]) max = q[i]; else if (min > q[i]) min = q[i]; } if (max == min) { max = 1.; min = -1.; } */ max = 1.2; min = 0.; draw_qvalue1(x+w/3,y,w/3,h/3,min,max,q[ActionUp]); draw_qvalue1(x+w/3,y+h*2/3,w/3,h/3,min,max,q[ActionDown]); draw_qvalue1(x,y+h/3,w/3,h/3,min,max,q[ActionLeft]); draw_qvalue1(x+w*2/3,y+h/3,w/3,h/3,min,max,q[ActionRight]); } #define NFrames 5 static void draw_agent(ox,oy,nx,ny,time) short nx,ny,ox,oy,time; { int x, y; ox = CellX(ox) + 1; oy = CellY(oy) + 1; nx = CellX(nx) + 1; ny = CellY(ny) + 1; x = (ox * (NFrames-1 - time) + nx * time) / (NFrames-1); y = (oy * (NFrames-1 - time) + ny * time) / (NFrames-1); XFillArc(dpy,backmap,gc,x,y, (int)(CellWidth-2),(int)(CellHeight-2),0,360*64); } draw_world_time(time) short time; { int i, j, x, y, w, h; char c; XSetForeground(dpy,gc,bg); XFillRectangle(dpy,backmap,gc,0,0,Width,Height); for (j = 0; j < VGrids; j ++) for (i = 0; i < HGrids; i ++) draw_qvalue(i,j,A.QTable[j][i]); XSetForeground(dpy,gc,fg); for (i = 0; i <= HGrids; i ++) { x = i * (Width - 1) / HGrids; XDrawLine(dpy,backmap,gc,x,0,x,Height-1); } for (i = 0; i <= VGrids; i ++) { y = i * (Height - 1) / VGrids; XDrawLine(dpy,backmap,gc,0,y,Width-1,y); } for (j = 0; j < VGrids; j ++) for (i = 0; i < HGrids; i ++) { x = CellX(i); y = CellY(j); switch (World[j][i]) { case W_Obstacle: XFillRectangle(dpy,backmap,gc,x,y, CellX(i+1)-x,CellY(j+1)-y); break; case W_Start: case W_Goal: c = World[j][i]; x += (CellWidth - XTextWidth(stepFont,&c,1)) / 2; y += (CellHeight - stepFont->max_bounds.ascent - stepFont->max_bounds.descent) / 2 + stepFont->max_bounds.ascent; XDrawString(dpy,backmap,gc,x,y,&c,1); } } draw_agent(A.x,A.y,A.newx,A.newy,time); XCopyArea(dpy,backmap,window,gc,0,0,Width,Height,0,0); } draw_world(smooth) int smooth; { short i; if (smooth) for (i = 1; i < NFrames; i ++) draw_world_time(i); else draw_world_time(NFrames-1); }