/* generates a move according to the walling algorithm Three cases (agent is at > moving east: #. > Rotate left # > Move ahead . > Move ahead */ void wallmove(clientinfo_t* client, int* dr, int* dc) { char backleft=backleftcorner(client, *dr, *dc); char left=leftchar(client, *dr, *dc); if ((backleft=='#') && (left==' ')) { // printf("Triggered left turn\n"); // fflush(stdout); rotateright(dr, dc); rotateright(dr, dc); // lazy left turn rotateright(dr, dc); // now either this is clear or blocked by agent if (blockedbyagent(client, *dr, *dc)) { printf("H\n"); fflush(stdout); return; } // not blocked so move forward printf("%c\n", fwdmove(*dr, *dc)); fflush(stdout); return; } for (int i=0;i<4;++i) { if ((fwdchar(client, *dr, *dc)==' ')) { if (blockedbyagent(client, *dr, *dc)) { printf("H\n"); fflush(stdout); return; } // not blocked so move forward printf("%c\n", fwdmove(*dr, *dc)); fflush(stdout); return; } // we must be blocked fwd so rotate and try again rotateright(dr, dc); } // if we get here, we must be surrounded printf("H\n"); fflush(stdout); }
/** \brief Rotate and stretch a canvas, 90 degrees counterclockwise. * * Apply a 90-degree transformation to a canvas, choosing characters * that look like the rotated version wherever possible. Some characters * will stay unchanged by the process, some others will be replaced by * close equivalents. Fullwidth characters will be lost. The operation is * not guaranteed to be reversible at all. * * Note that the width and height of the canvas are swapped, causing its * aspect ratio to look stretched. * * If an error occurs, -1 is returned and \b errno is set accordingly: * - \c EBUSY The canvas is in use by a display driver and cannot be rotated. * - \c ENOMEM Not enough memory to allocate the new canvas size. If this * happens, the previous canvas handle is still valid. * * \param cv The canvas to rotate left. * \return 0 in case of success, -1 if an error occurred. */ int caca_stretch_left(caca_canvas_t *cv) { uint32_t *newchars, *newattrs; int x, y; if(cv->refcount) { seterrno(EBUSY); return -1; } /* Save the current frame shortcuts */ _caca_save_frame_info(cv); newchars = malloc(cv->width * cv->height * sizeof(uint32_t)); if(!newchars) { seterrno(ENOMEM); return -1; } newattrs = malloc(cv->width * cv->height * sizeof(uint32_t)); if(!newattrs) { free(newchars); seterrno(ENOMEM); return -1; } for(y = 0; y < cv->height; y++) { for(x = 0; x < cv->width; x++) { uint32_t ch, attr; ch = cv->chars[cv->width * y + x]; attr = cv->attrs[cv->width * y + x]; /* FIXME: do something about fullwidth characters */ ch = leftchar(ch); newchars[cv->height * (cv->width - 1 - x) + y] = ch; newattrs[cv->height * (cv->width - 1 - x) + y] = attr; } } free(cv->chars); free(cv->attrs); /* Swap X and Y information */ x = cv->frames[cv->frame].x; y = cv->frames[cv->frame].y; cv->frames[cv->frame].x = y; cv->frames[cv->frame].y = cv->width - 1 - x; x = cv->frames[cv->frame].handlex; y = cv->frames[cv->frame].handley; cv->frames[cv->frame].handlex = y; cv->frames[cv->frame].handley = cv->width - 1 - x; cv->frames[cv->frame].width = cv->height; cv->frames[cv->frame].height = cv->width; cv->frames[cv->frame].chars = newchars; cv->frames[cv->frame].attrs = newattrs; /* Reset the current frame shortcuts */ _caca_load_frame_info(cv); caca_add_dirty_rect(cv, 0, 0, cv->width, cv->height); return 0; }