プログラム完成

後、これの解説をレポートにまとめなきゃなんないんですよねぇ。
戦略とかは、まぁ書くべきだとは思いますが、コメント付きのプログラムリストも載せるのに、わざわざプログラムを見なくても何をするかがわかるような解説、書かせる必要はないですよねぇ……
 
完成ついでに全文貼り付けてみる。(約180行)

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/*最大解析深度*/
#define MAXDEPTH 5

/*ログ解析&次の手予想の関数*/
unsigned short logcheck(unsigned short depth);

/*プレイヤーの手のログ用構造体*/
struct{
        unsigned short *ary;/*ログ記憶配列*/
        unsigned short size;/*配列サイズ*/
        unsigned short cnt;/*現在の記憶数*/
} log;

int main(void){
    unsigned short /*PC側の手*/cpu,/*プレイヤーの手*/p;
#ifdef _DEBUG
    unsigned short i;/*デバッグ時に使用するカウンタ変数*/
#endif
    char tmp[4];/*入力受付用文字列*/
    char hand[3][7]={{"グー"},{"チョキ"},{"パー"}};/*手表示用配列*/
    unsigned short game[3]={0,0,0};/*勝敗カウンタ*/
    
    /*ログのサイズ設定*/
    log.size = 10;
    log.ary  = malloc(sizeof(unsigned short)*log.size);
    
    /*乱数初期化*/
    srand((unsigned)time(NULL));
    
    /*メイン(無限)ループ*/
    for(log.cnt=0;1;log.cnt++){
        /*PC側の手を決定*/
        cpu = logcheck( MAXDEPTH );
        
#ifdef _DEBUG
        printf("%d\n",cpu);/*PC側の手を表示(デバッグ用)*/
#endif
        /*入力の受付*/
        printf("グーチョキパーをそれぞれ1,2,3として入力してください。(1,2,3以外で終了)\n");
        scanf("%3s",&tmp);
        p=(unsigned short)atoi(tmp);/*文字列を数値へ*/
        if(p<1||3<p)break;/*範囲外なら終了*/
        fflush(stdin);/*次回入力のためのバッファ消去*/
        
        printf("あなたの手    : %s\nコンピュータの手 : %s\n",hand[p-1],hand[cpu]);
        
        /*プレイヤーの出した手をログに記憶*/
        log.ary[log.cnt]=p;
        
        /*勝敗判定と結果の記憶*/
        switch((cpu-p+4)%3){
            case 0:
                printf("あいこです。\n");
                game[2]++;
                break;
            case 1:
                printf("あなたの勝ちです。\n");
                game[0]++;
                break;
            case 2:
                printf("あなたの負けです。\n");
                game[1]++;
                break;
        }
        
#ifdef _DEBUG
        /*プレイヤーの手のログを表示(デバッグ用)*/
        for(i=0;i<=log.cnt;i++)
            printf("%d ",log.ary[i]);
        printf("\n");
#endif
        /*手を記憶するログのサイズが足らなくなったら再確保*/
        if(log.cnt>=log.size-1){
            log.size +=(short) 10;
            log.ary=realloc(log.ary,sizeof(unsigned short)*log.size);
        }
    }
    
    printf("\n%d戦して、あなたは%d勝%d敗%d分け、勝率%.3lfでした。\n",log.cnt,game[0],game[1],game[2],(float)(game[0])/(float)(log.cnt==0?1:log.cnt));
    
    /*割り当てたメモリを解放*/
    free(log.ary);
    return 0;
}

/*ログ解析&次の手予想の関数*/
unsigned short logcheck(unsigned short depth/*解析深度*/){
    unsigned short i,j,k;/*全てカウンタ変数*/
    unsigned short ptn[3]={0,0,0};/*出現パターン記憶用配列*/
    unsigned short lmt;/*近似の揺れの範囲*/
    
    if(log.cnt<depth){
        if(log.cnt<3)
            return (unsigned short)(rand()%3);
        else
            depth=(unsigned short)(log.cnt-1);
    }
    
    /*指定深度以下でのパターンの検索*/
    for(i=1;i<=depth;i++){
        for(j=0;j<log.cnt-i-1;j++){
            for(k=0;k<i;k++){
                if(log.ary[j+k]!=log.ary[(log.cnt-i)+k])
                    break;/*パターン合致しなければ脱出*/
            }
            /*パターン合致(forが完了)したならば、そのパターンでの予想を記憶
            長いパターンに合致した時ほど、記憶時に加算する値を大きくする*/
            if(k>=i)
                ptn[log.ary[j+i]-1]+=i;
        }
    }
    
#ifdef _DEBUG
    /*パターンの出現回数(デバッグ)*/
    printf("%2d %2d %2d  ",ptn[0],ptn[1],ptn[2]);
#endif
    
    /*近似の揺れの決定*/
    if(ptn[0]>ptn[1]){
        if(ptn[0]>ptn[2])
            lmt=(unsigned short)(ptn[0]/5);
        else
            lmt=(unsigned short)(ptn[1]/5);
    }else{
        if(ptn[1]>ptn[2])
            lmt=(unsigned short)(ptn[1]/5);
        else
            lmt=(unsigned short)(ptn[2]/5);
    }
    
    /*記憶した出現回数に併せて予想を立てる*/
    if(abs(ptn[0]-ptn[1])<=lmt){/*グーとチョキがほぼ同数か?*/
        if(abs(ptn[1]-ptn[2])<=lmt){/*チョキとパーがほぼ同数か?*/
            return (short)(rand()%3);/*予想不能(全部ほぼ同じ回数)*/
        }else if(ptn[1]<ptn[2]){
            return 1;/*パーを予想*/
        }else{
            if(abs(ptn[2]*1.5-ptn[1])<=lmt){/*パーがそこそこ多いか?*/
                return (short)((rand()%2)*2);/*グーかチョキを予想(パーも結構ある)*/
            }else{
                return 0;/*グーかチョキを予想(パーは少ない)*/
            }
        }
    }else if(ptn[0]>ptn[1]){
        if(abs(ptn[0]-ptn[2])<=lmt){/*グーとパーがほぼ同数か?*/
            if(abs(ptn[1]*1.5-ptn[2])<=lmt){/*チョキがそこそこ多いか?*/
                return (short)((rand()%2)+1);/*グーかパーを予想(チョキも結構ある)*/
            }else{
                return 2;/*グーかパーを予想(チョキは少ない)*/
            }
        }else if(ptn[0]>ptn[2]){
            return 2;/*グーを予想*/
        }else{
            return 1;/*パーを予想*/
        }
    }else{
         if(abs(ptn[1]-ptn[2])<=lmt){/*チョキとパーがほぼ同数か?*/
            if(abs(ptn[0]*1.5-ptn[1])<=lmt){/*グーがそこそこ多いか?*/
                return (unsigned short)((rand()%2));/*チョキかパーを予想(グーも結構ある)*/
            }else{
                return 1;/*チョキかパーを予想(グーは少ない)*/
            }
        }else if(ptn[1]>ptn[2]){
            return 0;/*チョキを予想*/
        }else{
            return 1;/*パーを予想*/
        }
    }
}