]> git.cworth.org Git - rrsolve/blobdiff - src/rrsolve.c
Always issue NOBID after bidding. Fixed to use game from command line.
[rrsolve] / src / rrsolve.c
index 4e2efae180a4e174d4fa128da84b93ce2d86f873..1057481222568558e3f3f787f03820a5fe40a908 100644 (file)
 
 #include "rrsolve.h"
 
-#define HOST "localhost"
-#define PORT "5252"
-#define USER "rrsolve"
-#define GAME "game"
-
 /* Tuning this can reduce excess reallocs */
 #define RRS_BRANCHING_FACTOR_ESTIMATE 10
 
@@ -74,67 +69,6 @@ trace_solution (rr_board_t *board,
                rrs_state_t solution_state,
                rrs_solution_t *solution);
 
-char TOUGH[] = "\n"
-" === === === === === === === === === === === === === === === === \n"
-"|... ... ... ...|r.. ... ... ... ... ... ... ...|... ... ... ...|\n"
-"                                                     ===         \n"
-"|... ... ... ... ... ... ... ... ... ... ... ... ...|.rs Y.. ...|\n"
-"                                                                 \n"
-"|... ... ... ... ... .bo|... ... ... .bt|... ... ... ... ... ...|\n"
-"                     ===             ===                         \n"
-"|... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...|\n"
-"                                                             === \n"
-"|... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...|\n"
-"         ===                                                     \n"
-"|... ... .gc|... ... ... ...|.rt ... ... ... ... ... ...|.go ...|\n"
-" ===                         ===             ===         ===     \n"
-"|... ... ... ... ... ... ... ... ... ... ... .yc|... ... ... ...|\n"
-"     ===                     === ===                             \n"
-"|...|.YS ... ... ... ... ...|... ...|... ... ... ... ... ... ...|\n"
-"                                                 ===             \n"
-"|... ... ... ... ... ... ...|... ...|... ... ...|.ww ... ... ...|\n"
-"     ===             ===     === ===                             \n"
-"|... .yo|... ... ...|bbs ... ... ... ...|.bc ... ... ... ... ...|\n"
-"                                         ===                     \n"
-"|... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...|\n"
-" ===                                                         === \n"
-"|... ... ... ... ... ... ... ... ... .yt|... ... ... ... ... ...|\n"
-"                                     ===                 ===     \n"
-"|... ... ... ... ... ... .rc|... ... ... ... ... ... ... .gs|...|\n"
-"                         ===                                     \n"
-"|... ... ... ... ... ... ... ... ... ... ... ... ... ... ... g..|\n"
-"                                                     ===         \n"
-"|... ...|.gt ... ... ... ... ... ... ... ... ... ...|.ro ... ...|\n"
-"         ===                                                     \n"
-"|... ... ... ... ... ...|... ... ... ... ...|... ... ... ... ...|\n"
-" === === === === === === === === === === === === === === === === ";
-/*
-Move #1 generated 11 new states.
-Move #2 generated 59 new states.
-Move #3 generated 216 new states.
-Move #4 generated 640 new states.
-Move #5 generated 1701 new states.
-Move #6 generated 4239 new states.
-Move #7 generated 10041 new states.
-Move #8 generated 22678 new states.
-Move #9 generated 49103 new states.
-Move #10 generated 102154 new states.
-Move #11 generated 204086 new states.
-Move #12 generated 391534 new states.
-Move #13 generated 722808 new states.
-Move #14 generated 1285932 new states.
-Move #15 generated 2204971 new states.
-Found solution of 16 moves in 3694.8 seconds.
-Traced solution in 0.052438 seconds.
-Solution (16 moves):
-    Move #0: yellow east, south, west
-Move #3: green south, west, north
-Move #6: blue east, north, west, south
-Move #10: yellow south, east, south
-Move #13: green west
-Move #14: yellow north
-*/
-
 int
 main (int argc, char *argv[])
 {
@@ -144,24 +78,41 @@ main (int argc, char *argv[])
 
     args_parse (&args, argc, argv);
 
-    client = rr_client_create (args.host, args.port, args.user);
-    if (client == NULL) {
-       fprintf (stderr, "Failed connecting to %s:%s as %s\n",
-                args.host, args.port, args.user);
-       return 1;
-    }
+    if (args.files) {
+       int i;
+       rr_board_t *board;
+       rrs_solution_t solution;
 
-    status = rr_client_join (client, GAME);
-    if (status == RR_STATUS_NO_GAME)
-       status = rr_client_new (client, GAME);
-    if (status) {
-       fprintf (stderr, "Error joining or creating game: %s\n", rr_status_str (status));
-       return 1;
-    }
+       for (i = 0; args.files[i]; i++) {
+           board = rr_board_create_from_file (args.files[i]);
+           if (board == NULL)
+               continue;
+           rrs_solution_init (&solution);
+           solve_board (board, &solution);
+           rrs_solution_print (&solution);
+           rrs_solution_fini (&solution);
+           rr_board_destroy (board);
+       }
+    } else {
+       client = rr_client_create (args.host, args.port, args.user);
+       if (client == NULL) {
+           fprintf (stderr, "Failed connecting to %s:%s as %s\n",
+                    args.host, args.port, args.user);
+           return 1;
+       }
+
+       status = rr_client_join (client, args.game);
+       if (status == RR_STATUS_NO_GAME)
+           status = rr_client_new (client, args.game);
+       if (status) {
+           fprintf (stderr, "Error joining or creating game: %s\n", rr_status_str (status));
+           return 1;
+       }
 
-    handle_events (client);
+       handle_events (client);
 
-    rr_client_destroy (client);
+       rr_client_destroy (client);
+    }
 
     return 0;
 }
@@ -173,43 +124,66 @@ handle_events (rr_client_t *client)
     rr_status_t status;
     rr_notice_t *notice;
     rrs_solution_t solution;
-    rr_board_t *board = NULL;
+    rr_board_t *board;
     char *diagram;
     struct timespec move_delay = { 1, 200000000l };
 
+    /* XXX: This block of code can go away when add a NOTICE BOARD
+       for new users joining a game. */
+    {
+       status = rr_client_show (client, &diagram);
+       if (status) {
+           fprintf (stderr, "Error in rr_client_show: %s\n", rr_status_str (status));
+           goto DONE;
+       }
+       board = rr_board_create_from_str (diagram);
+       free (diagram);
+    }
+
+    /* XXX: This block of code can go away when we add a NOTICE TURN
+       for new users joining a game in progress. */
+    {
+       rrs_solution_init (&solution);
+       solve_board (board, &solution);
+       rr_client_bid (client, solution.num_moves);
+       rr_client_nobid (client);
+    }
+
     while (1) {
        status = rr_client_next_notice (client, &notice);
        if (status) {
-           fprintf (stderr, "ERROR during rr_client_next_notice: %s\n",
-                    rr_status_str (status));
+           if (status == RR_STATUS_EOF)
+               fprintf (stderr, "Server has disconnected. Exiting.\n");
+           else
+               fprintf (stderr, "ERROR during rr_client_next_notice: %s\n",
+                        rr_status_str (status));
            return;
        }
-
-       printf ("Received notice of type %d\n", notice->type);
+       if (!notice) {
+           fprintf (stderr, "No notice during rr_client_next_notice\n");
+           continue;
+       }
 
        switch  (notice->type) {
+       /* XXX: The processing needed for GAMEOVER, JOIN, and TURN
+          is a mess right now. There should be one NOTICE to say
+          the board has changed and one to say a TURN has started,
+          rather than the current mess. */
        case RR_NOTICE_GAMEOVER:
-       case RR_NOTICE_JOIN:
            status = rr_client_show (client, &diagram);
            if (status) {
                fprintf (stderr, "Error in rr_client_show: %s\n", rr_status_str (status));
                goto DONE;
            }
-           if (board == NULL)
-               board = rr_board_create_from_str (diagram);
-           else
-               rr_board_parse (board, diagram);
-
-           /* XXX: Fixing the server to send a NOTICE TURN here would let me drop this code */
-           rrs_solution_init (&solution);
-           solve_board (board, &solution);
-           rr_client_bid (client, solution.num_moves);
+           rr_board_parse (board, diagram);
+           free (diagram);
            break;
        case RR_NOTICE_TURN:
            rr_board_set_goal_target (board, notice->u.target);
            rrs_solution_init (&solution);
            solve_board (board, &solution);
            rr_client_bid (client, solution.num_moves);
+           rr_client_nobid (client);
            break;
        case RR_NOTICE_ACTIVATE:
            for (i = 0; i < solution.num_moves; i++) {
@@ -247,6 +221,7 @@ handle_events (rr_client_t *client)
            break;
        case RR_NOTICE_GAME:
        case RR_NOTICE_USER:
+       case RR_NOTICE_JOIN:
        case RR_NOTICE_QUIT:
        case RR_NOTICE_DISPOSE:
        case RR_NOTICE_MESSAGE:
@@ -263,9 +238,12 @@ handle_events (rr_client_t *client)
            /* Ignore these notices */
            break;
        }
+       free (notice);
     }
 
   DONE:
+    if (notice)
+       free (notice);
     if (board)
        rr_board_destroy (board);
 }
@@ -284,7 +262,7 @@ rrs_solution_print (rrs_solution_t *solution)
            printf (", %s", rr_direction_str (move->dir));
        else
            printf ("\n Move #%d: %s %s",
-                   i, rr_robot_str (move->robot), rr_direction_str (move->dir));
+                   i+1, rr_robot_str (move->robot), rr_direction_str (move->dir));
        last_robot = move->robot;
     }
     printf ("\n");
@@ -442,8 +420,10 @@ trace_solution (rr_board_t *board,
     rr_status_t status;
     int i, j;
     rrs_state_buf_t *buf;
-    rr_robot_t robot;
-    rr_direction_t dir;
+    int found_move;
+    rr_robot_t robot, robot_found, last_robot_found = RR_ROBOT_NONE;
+    rr_direction_t dir, dir_found;
+    rrs_state_t state_found;
 
     for (i = moves-1; i >= 0; i--) {
        buf = states[i];
@@ -454,18 +434,27 @@ trace_solution (rr_board_t *board,
                status = rr_board_move (board, robot, dir);
                if (status == RR_STATUS_SUCCESS) {
                    if (rrs_state_get_from_board (board) == solution_state) {
-                       rrs_solution_prepend (solution, robot, dir);
-                       solution_state = buf->state[j];
-                       goto NEXT_MOVE;
+                       found_move = 1;
+                       robot_found = robot;
+                       dir_found = dir;
+                       state_found = buf->state[j];
+                       if (robot_found == last_robot_found)
+                           goto NEXT_MOVE;
+                       else
+                           last_robot_found = robot_found;
                    }
                }
            }
        }
-       fprintf (stderr, "ERROR: Failed to trace solution backwards to 0x%x at move %d\n",
-                solution_state, i+1);
-       break;
       NEXT_MOVE:
-       ;
+       if (found_move) {
+           rrs_solution_prepend (solution, robot_found, dir_found);
+           solution_state = state_found;
+       } else {
+           fprintf (stderr, "ERROR: Failed to trace solution backwards to 0x%x at move %d\n",
+                    solution_state, i+1);
+           break;
+       }
     }
 }