#include #include #include #include #include #include #include #include "smaze.h" XtAppContext app_con; Widget app_sh; Display *dpy; static Boolean Running = False; int DisplayOn = 1; static String fallback_resources[] = { "*FontList: variable", "*background: grey90", "*draw.width: 610", "*draw.height: 407", "*work.width: 400", "*work.height: 400", "*scale.scaleWidth: 200", NULL }; typedef struct { long seed_random; } ApplicationData, *ApplicationDataPtr; ApplicationData AppData; static XrmOptionDescRec options[] = { {"-srand","*seedRandom",XrmoptionSepArg,NULL} }; #define N_OPTIONS 1 static XtResource resources[] = { {"seedRandom", "SeedRandom", XtRInt, sizeof(long), XtOffset(ApplicationDataPtr, seed_random), XtRImmediate, (XtPointer)0} }; static Window stepWindow; static unsigned int stepWidth, stepHeight; static unsigned long stepfg, stepbg; unsigned long fg, bg; XFontStruct *stepFont; static int stepX, stepY; extern GC gc; set_step_label(step) unsigned long step; { int right; char buf[64]; sprintf(buf,"%8d",step); right = stepX + XTextWidth(stepFont,buf,strlen(buf)); XSetForeground(dpy,gc,stepfg); XDrawImageString(dpy,stepWindow,gc,stepX,stepY,buf,strlen(buf)); XSetForeground(dpy,gc,stepbg); XFillRectangle(dpy,stepWindow,gc,right,0,stepWidth-right,stepHeight); } static void step_label_init(w) Widget w; { Window root; int x, y; unsigned int border,depth; XmFontList fontList; XmFontContext context; XmStringCharSet charset; stepWindow = XtWindow(w); XGetGeometry(dpy,stepWindow,&root,&x,&y, &stepWidth,&stepHeight,&border,&depth); XtVaGetValues(w,XmNforeground,&stepfg,XmNbackground,&stepbg, XmNfontList,&fontList,NULL); XmFontListInitFontContext(&context, fontList); XmFontListGetNextFont(context, &charset, &stepFont); stepX = 0; stepY = stepHeight - stepFont->max_bounds.descent - 2; XSetBackground(dpy,gc,stepbg); XSetFont(dpy,gc,stepFont->fid); set_step_label(0); } static void closeCB(w,cl,cd) Widget w; XtPointer cl,cd; { XtPopdown((Widget)cl); } static void strategyCB(w,cl,cd) Widget w; XtPointer cl,cd; { extern LearningStrategy Strategy; Strategy = (LearningStrategy)cl; } static void scaleCB(w,cl,cd) Widget w; XtPointer cl,cd; { int value; XtVaGetValues(w,XmNvalue,&value,NULL); *((double *)cl) = value * 0.01; } static Widget create_parameter_shell() { extern double InitialQValue, ExplorationRate, LearningRate, DiscountRate; static struct scl_rec { char *label; double *var; } scl[] = { {"Initial Q-value",&InitialQValue}, {"Exploration rate",&ExplorationRate}, {"Learning rate",&LearningRate}, {"Discount rate",&DiscountRate},{NULL} }; static struct stg_rec { char *name; LearningStrategy stg; } stg[] = { {"One step Q",OneStepQ},{"Dyna Q",DynaQ}, {"Back propagation Q",BackPropQ},{NULL} }; struct scl_rec *s; struct stg_rec *t; int n, m; Arg args[6]; XmString str; Widget shell, box, w, menu; shell = XtCreatePopupShell("parameter", topLevelShellWidgetClass,app_sh,NULL,0); XtManageChild(box=XmCreateRowColumn(shell,"box",NULL,0)); str = XmStringCreateSimple("Strategy"); n = 0; XtSetArg(args[n],XmNlabelString,str); n++; XtManageChild(w=XmCreateOptionMenu(box,"strategy",args,n)); menu = XmCreatePulldownMenu(w,"menu",NULL,0); XtVaSetValues(w,XmNsubMenuId,menu,NULL); for (t = stg; t->name; t++) { XtManageChild(w=XmCreatePushButton(menu,t->name,NULL,0)); XtAddCallback(w,XmNactivateCallback,strategyCB, (XtPointer)(t->stg)); } n = 0; XtSetArg(args[n],XmNshowValue,True); n++; XtSetArg(args[n],XmNorientation,XmHORIZONTAL); n++; XtSetArg(args[n],XmNdecimalPoints,2); n++; XtSetArg(args[n],XmNscaleWidth,240); n++; m = n; n += 2; for (s = scl; s->label; s ++) { XtSetArg(args[m],XmNvalue,(int)(*(s->var)*100.)); str = XmStringCreateSimple(s->label); XtSetArg(args[m+1],XmNtitleString,str); XtManageChild(w=XmCreateScale(box,"scale",args,n)); XtAddCallback(w,XmNvalueChangedCallback, scaleCB,(XtPointer)(s->var)); XmStringFree(str); } return shell; } static Boolean one_step_proc(cl) XtPointer cl; { int i; if (DisplayOn) one_step(); else for (i = 0; i < 100; i ++) one_step(); return !Running; } static void QuitCB(w,cl,cd) Widget w; XtPointer cl,cd; { exit(0); } static void ResetCB(w,cl,cd) Widget w; XtPointer cl,cd; { domain_reset(); monitor_reset(); } static void RunCB(w,cl,cd) Widget w; XtPointer cl,cd; { if (Running = !Running) XtAppAddWorkProc(app_con,one_step_proc,NULL); } static void StepCB(w,cl,cd) Widget w; XtPointer cl,cd; { if (Running) Running = False; else one_step(); } static void DisplayCB(w,cl,cd) Widget w; XtPointer cl,cd; { display_switch(DisplayOn = !DisplayOn); } static void DestroyCB(w,cl,cd) Widget w; XtPointer cl,cd; { ((Widget *)cl)[0] = NULL; XtVaSetValues(((Widget *)cl)[1],XmNset,False,NULL); } static void window_switch(w,cd,s,proc) XtPointer cd; Widget w, s[], (*proc)(); { if (((XmToggleButtonCallbackStruct *)cd)->set) { if (!s[0]) { s[0] = (*proc)(); s[1] = w; XtAddCallback(s[0],XmNdestroyCallback,DestroyCB, (XtPointer)s); } XtPopup(s[0],XtGrabNone); } else if (s[0]) XtPopdown(s[0]); } extern Widget create_monitor_shell(); static void MonitorCB(w,cl,cd) Widget w; XtPointer cl,cd; { static Widget s[2] = {NULL}; window_switch(w,cd,s,create_monitor_shell); monitor_switch(((XmToggleButtonCallbackStruct *)cd)->set); } static void ParameterCB(w,cl,cd) Widget w; XtPointer cl,cd; { static Widget s[2] = {NULL}; window_switch(w,cd,s,create_parameter_shell); } static void ExposeCB(w,cl,cd) Widget w; XtPointer cl,cd; { redisplay(((XmDrawingAreaCallbackStruct *)cd)->event); } static void InputCB(w,cl,cd) Widget w; XtPointer cl,cd; { check_input(((XmDrawingAreaCallbackStruct *)cd)->event); } static void create_menu_bar(bar) Widget bar; { static struct bt_rec { char *name; XtCallbackProc proc; } bts[] = { {"Quit",QuitCB},{"Reset",ResetCB},{"Run",RunCB}, {"Step",StepCB},{NULL} }; static struct tgl_rec { char *name; XtCallbackProc proc; Boolean set; } tgls[] = { {"Map display",DisplayCB,True},{"Monitor",MonitorCB,False}, {"Parameter",ParameterCB,False},{NULL} }; Widget button, menu; struct bt_rec *b; struct tgl_rec *t; Arg args[1]; for (b = bts; b->name; b++) { XtManageChild(button=XmCreateCascadeButton(bar,b->name,NULL,0)); XtAddCallback(button,XmNactivateCallback,b->proc,NULL); } XtManageChild(button=XmCreateCascadeButton(bar,"Window",NULL,0)); menu = XmCreatePulldownMenu(button,"windowMenu",NULL,0); XtVaSetValues(button,XmNsubMenuId,menu,NULL); for (t = tgls; t->name; t ++) { XtSetArg(args[0],XmNset,t->set); XtManageChild(button=XmCreateToggleButton(menu,t->name,args,1)); XtAddCallback(button,XmNvalueChangedCallback,t->proc,NULL); } } main(argc,argv) int argc; char *argv[]; { Widget main, bar, label, draw; app_sh = XtAppInitialize(&app_con,argv[0],options,N_OPTIONS, &argc,argv,fallback_resources,NULL,0); XtGetApplicationResources(app_sh,(XtPointer)&AppData,resources, XtNumber(resources),NULL,0); srand48(AppData.seed_random ? AppData.seed_random : time(0)); XtManageChild(main=XmCreateMainWindow(app_sh,"main",NULL,0)); XtManageChild(bar=XmCreateMenuBar(main,"bar",NULL,0)); create_menu_bar(bar); XtManageChild(draw=XmCreateDrawingArea(main,"draw",NULL,0)); XtAddCallback(draw,XmNexposeCallback,ExposeCB,NULL); XtAddCallback(draw,XmNinputCallback,InputCB,NULL); XtManageChild(label=XmCreateLabel(main,"stepLabel",NULL,0)); XtVaSetValues(main,XmNmessageWindow,label,NULL); XtRealizeWidget(app_sh); dpy = XtDisplay(draw); XtVaGetValues(draw,XmNforeground,&fg,XmNbackground,&bg,NULL); draw_init(XtWindow(draw)); step_label_init(label); domain_reset(); XtAppMainLoop(app_con); }