/* * hiq.c -- Solution for HiQ code test "Simulator for radio controlled cars." * * Copyright (C) 2018 Andreas Forsgren * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include #include #include #define VERSION 1 static char *prgpath, *prgname; static void usage(FILE *output, int help) { fprintf(output, "usage: %s -h | " "[command...] | -v\n", prgpath); if (help) { fprintf(output, "usage: %s 8 6 2 3 north # 8x6 " "room & pos. 2,3 & face north\n", prgpath); fprintf(output, "usage: %s 8 6 2 3 n fffrfflbb # same & " "move/rot. f*3>r>f*2>l>b*2\n", prgpath); fprintf(output, "usage: %s -v # display " "version\n", prgpath); } } static void version(void) { printf("%d\n", VERSION); } int main(int argc, char *argv[]) { int width, height, x, y; char head, *cmd = ""; prgpath = argv[0]; prgname = strrchr(prgpath, '/'); if (prgname != NULL) prgname++; else prgname = prgpath; if (argc == 2) { if (strcmp(argv[1], "-h") == 0) usage(stdout, 1); else if (strcmp(argv[1], "-v") == 0) version(); else { fprintf(stderr, "%s: unknown argument '%s'\n", prgname, argv[1]); return 1; } return 0; } else if (argc == 6 || argc == 7) { width = atoi(argv[1]); if (width < 1) { fprintf(stderr, "%s: width must be >= 1\n", prgname); return 1; } height = atoi(argv[2]); if (height < 1) { fprintf(stderr, "%s: height must be >= 1\n", prgname); return 1; } x = atoi(argv[3]); if (x < 1 || x > width) { fprintf(stderr, "%s: x must be >= 1 and <= width\n", prgname); return 1; } y = atoi(argv[4]); if (y < 1 || y > height) { fprintf(stderr, "%s: y must be >= 1 and <= height\n", prgname); return 1; } head = *argv[5]; /* Just grabbing the 1st character is a nice feature as the user can specify e.g. north and it will work as expected. */ if (head != 'n' && head != 's' && head != 'w' && head != 'e') { fprintf(stderr, "%s: invalid heading %c\n", prgname, head); return 1; } if (argc == 7) cmd = argv[6]; } else { usage(stderr, 0); return 1; } do { #ifdef DEBUG fprintf(stderr, "%s: debug: width=%d height=%d x=%d y=%d " "head=%c cmd='%c'\n", prgname, width, height, x, y, head, *cmd); #endif switch (*cmd) { case '\0': break; case 'f': case 'b': switch (head) { case 'n': if (*cmd == 'f') y++; else y--; break; case 's': if (*cmd == 'f') y--; else y++; break; case 'w': if (*cmd == 'f') x--; else x++; break; case 'e': if (*cmd == 'f') x++; else x--; break; } break; case 'l': case 'r': switch (head) { case 'n': head = (*cmd == 'l') ? 'w' : 'e'; break; case 's': head = (*cmd == 'l') ? 'e' : 'w'; break; case 'w': head = (*cmd == 'l') ? 's' : 'n'; break; case 'e': head = (*cmd == 'l') ? 'n' : 's'; break; } break; default: fprintf(stderr, "%s: unknown command '%c'\n", prgname, *cmd); return 1; } if (x < 1 || x > width || y < 1 || y > height) { fprintf(stderr, "%s: invalid position x=%d y=%d " "reached when heading %c and last command '%c' " "(\"wall hit\")\n", prgname, x, y, head, *cmd); return 1; } } while (*cmd++ != '\0'); printf("%d %d %c\n", x, y, head); return 0; }