tictactoe

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

unit_test.c (3083B)


      1 #include <stdbool.h>
      2 #include <stdio.h>
      3 #define UNIT_TEST
      4 #define NO_PRINT_BOARD
      5 
      6 #include "tictactoe.c"
      7 
      8 struct test_board { char *name; char *expected_result; };
      9 
     10 struct test_board test_boards[] = {
     11     {"scratch_board", "SCRATCH"},
     12     {"x_wins_column", "X WINS" },
     13     {"x_wins_diag",   "X WINS" },
     14     {"x_wins_row",    "X WINS" },
     15     {"o_wins_column", "O WINS" },
     16     {"o_wins_diag",   "O WINS" },
     17     {"o_wins_row",    "O WINS" },
     18 };
     19 
     20 void print_test_header(int test_num, char *desc, char *ex_res) {
     21     printf("TEST %d\n", test_num);
     22     puts(  "--------");
     23     printf("Testing %s -- expecting %s ...\n", desc, ex_res);
     24 }
     25 bool print_test_results(int test_num, bool succeeded) {
     26     printf("Test %d ", test_num);
     27     if(succeeded) {
     28         puts("SUCCESS\n");
     29         return 0;
     30     }
     31     else {
     32         puts("FAILURE\n");
     33         return 1;
     34     }
     35 }
     36 
     37 bool test_ai_against(Get_move_fn get_o_move, int iters, int test_num, char *opp_desc, char *ex_res, bool wins_ok) {
     38     char desc[120];
     39     int i;
     40     int wins = 0, losses = 0;
     41     sprintf(desc, "our allegedly perfect AI against %s %d times", opp_desc, iters);
     42     print_test_header(test_num, desc, ex_res);
     43     for(i=0; i < iters; i++) {
     44         switch(play(get_move_minimax, get_o_move)) {
     45         case 'X': wins++; break;
     46         case 'O': losses++; break;
     47         }
     48     }
     49     printf("Results were: %d scratch; %d wins for X; %d wins for O\n", iters - wins - losses, wins, losses);
     50     return print_test_results(test_num, wins_ok ? !losses : !(wins || losses));
     51 }
     52 
     53 int main() {
     54     int failures = 0;
     55     int len = sizeof test_boards / sizeof test_boards[0];
     56     int i = 0;
     57     /* Testing that particular presets will be correctly interpreted as a draw/win/loss */
     58     while(i < len) {
     59         struct test_board *b = test_boards + (i++);
     60         char actual_result[8];
     61         print_test_header(i, b->name, b->expected_result);
     62         set_board(b->name);
     63         char winner = play(get_move_preset_board, NULL);
     64         if(winner)
     65             sprintf(actual_result, "%c WINS", winner);
     66         else
     67             sprintf(actual_result, "SCRATCH");
     68         printf("Result was: %s\n", actual_result);
     69         failures += print_test_results(i, !strcmp(actual_result, b->expected_result));
     70     }
     71     failures += test_ai_against(get_move_minimax, 500, ++i, "itself", "a draw for all executions", false);
     72     failures += test_ai_against(get_random_move, 500, ++i, "a random move generator", "the AI wins or draws for all executions", true);
     73     failures += test_ai_against(get_winning_move_else_random, 500, ++i, "a slightly dumber AI", "the AI wins or draws for all executions", true);
     74     failures += test_ai_against(get_winning_move_else_block_else_random, 500, ++i, "a slightly smarter, dumber AI", "the AI wins or draws for all executions", true);
     75 
     76     puts("-----------------------------------------------------------");
     77     printf("\n### SUITE %s ###\n", failures ? "FAILURE" : "SUCCESS");
     78     printf("%d tests: %d failed, %d succeeded\n", i, failures, i - failures);
     79     return (i - failures == 0) ? 2 : (failures && 1);
     80 }