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 }