/**************************************************/
/* Funktionen die per Mausklick aufgerufen werden */
/**************************************************/
function beginner(player) {
         if( status != 0 ) return;
         if( player == 1 ) status = 1;
         if( player != 1 ) { status = 2; window.setTimeout("computer()",1) }
}

function setze(x,y) {
         if( status == 0 ) status = 1;
         if( status != 1 ) return;
         if( readxy(x,y) != 0 ) return;
         gsetxy(x,y,kreuz);
         status = 2;
         check_win();
         window.setTimeout("computer()",1)
}

/****************************************************/
/* Funktionen zur initialisierung und zur Steuerung */
/****************************************************/
function init() {
        for(zeile=0; zeile<C_ROW; zeile++){
           for(spalte=0; spalte<C_COL; spalte++){
               gsetxy(spalte,zeile,leer);
           }
        }
        status=0;
}

function is_simple() {
         return document.lform.elements[0].checked;
}

function check_win() {
     /*** suche ob irgendwer gewonnen hat ***/
     winner=0;
     for(yyy=0; yyy<C_ROW; yyy++){ /* zunächst alle waagerechten */
         if( count_line(0, yyy, 1, 0, 1) == C_COL ) {
             for(xxx=0; xxx<C_COL; xxx++) gsetxy(xxx,yyy,rkreuz); winner=1; break;}
         if( count_line(0, yyy, 1, 0, 2) == C_COL ) {
             for(xxx=0; xxx<C_COL; xxx++) gsetxy(xxx,yyy,rkreis); winner=2; break;}
     }
     for(xxx=0; xxx<C_COL; xxx++){ /* dann alle senkrechten */
         if( count_line(xxx, 0, 0, 1, 1) == C_ROW ) {
             for(yyy=0; yyy<C_ROW; yyy++) gsetxy(xxx,yyy,rkreuz); winner=1; break;}
         if( count_line(xxx, 0, 0, 1, 2) == C_ROW ) {
             for(yyy=0; yyy<C_ROW; yyy++) gsetxy(xxx,yyy,rkreis); winner=2; break;}
     }
     if( count_line(0, 0, 1, 1, 1) == C_ROW ) { xxx=0; yyy=0;
         for(dummy=0; dummy<C_ROW; dummy++) gsetxy(xxx++,yyy++,rkreuz);  winner=1; }
     if( count_line(0, 0, 1, 1, 2) == C_ROW ) { yyy=0; xxx=0;
         for(dummy=0; dummy<C_ROW; dummy++) gsetxy(xxx++,yyy++,rkreis); winner=2; }
     if( count_line(C_COL-1, 0, -1, 1, 1) == C_ROW ) { yyy=0; xxx=C_COL-1;
         for(dummy=0; dummy<C_ROW; dummy++) gsetxy(xxx--,yyy++,rkreuz); winner=1; }
     if( count_line(C_COL-1, 0, -1, 1, 2) == C_ROW ) { yyy=0; xxx=C_COL-1;
         for(dummy=0; dummy<C_ROW; dummy++) gsetxy(xxx--,yyy++,rkreis); winner=2; }

     /* Test auf unentschieden */
     cnt_fields = 0;
     for(xxx=0; xxx<C_COL; xxx++){
         if( count_line(xxx, 0, 0, 1, 0) == 0 ) cnt_fields+=C_ROW;
     }
     if( (cnt_fields == C_ROW * C_COL) && winner == 0) {
        for( xxx=0; xxx<C_COL; xxx++) for(yyy=0; yyy<C_ROW; yyy++) {
             if( readxy(xxx,yyy) == 1 ) gsetxy(xxx,yyy,rkreuz);
             if( readxy(xxx,yyy) == 2 ) gsetxy(xxx,yyy,rkreis);
        }
        winner=4; /* unentschieden, nur wenn niemand mit letztem zug gewonnen hat */
     }
     //if( winner == 1 ) showtext("glückwunsch - sie haben gewonnen");
     //if( winner == 2 ) showtext("ich habe gewonnen!");
     if( winner != 0) status = 3;
}

/*****************/
/* KI Funktionen */
/*****************/
function computer() {
        if( status != 2 ) return;

        /*** suche ob ich irgendwo gewinnen kann ***/
        for(yyy=0; yyy<C_ROW; yyy++){ /* zunächst alle waagerechten */
            if( count_line(0, yyy, 1, 0, 1) > 0 ) continue;
            if( count_line(0, yyy, 1, 0, 2) == C_COL-1 ) { computer_move(free_x,free_y);  return; }
        }
        for(xxx=0; xxx<C_COL; xxx++){ /* dann alle senkrechten */
            if( count_line(xxx, 0, 0, 1, 1) > 0 ) continue;
            if( count_line(xxx, 0, 0, 1, 2) == C_ROW-1 ) { computer_move(free_x,free_y); return; }
        }
        if( count_line(0, 0, 1, 1, 1) == 0 ) { /* zum schluss die 2 diagonalen */
           if( count_line(0, 0, 1, 1, 2) == C_ROW-1 ) { computer_move(free_x,free_y);  return; }
        }
        if( count_line(C_COL-1, 0, -1, 1, 1) == 0 ) {
           if( count_line(C_COL-1, 0, -1, 1, 2) == C_ROW-1 ) { computer_move(free_x,free_y); return; }
        }

        /*** suche ob du irgendwo gewinnen kannst ***/
        for(yyy=0; yyy<C_ROW; yyy++){ /* zunächst alle waagerechten */
            if( count_line(0, yyy, 1, 0, 2) > 0 ) continue;
            if( count_line(0, yyy, 1, 0, 1) == C_COL-1 ) { computer_move(free_x,free_y);  return; }
        }
        for(xxx=0; xxx<C_COL; xxx++){ /* dann alle senkrechten */
            if( count_line(xxx, 0, 0, 1, 2) > 0 ) continue;
            if( count_line(xxx, 0, 0, 1, 1) == C_ROW-1 ) { computer_move(free_x,free_y); return; }
        }
        if( count_line(0, 0, 1, 1, 2) == 0 ) { /* zum schluss die 2 diagonalen */
           if( count_line(0, 0, 1, 1, 1) == C_ROW-1 ) { computer_move(free_x,free_y);  return; }
        }
        if( count_line(C_COL-1, 0, -1, 1, 2) == 0 ) {
           if( count_line(C_COL-1, 0, -1, 1, 1) == C_ROW-1 ) { computer_move(free_x,free_y); return; }
        }

        /* wenn noch nichts gesetzt, dann hier zwischen leicht und schwer unterscheiden */
        if( is_simple() ) {

            /*** wenn einfach, dann nach zufallsprinzip setzen ***/
            cnt=0; for( tt=0; tt<(C_COL*C_ROW); tt++ ) if( field[tt]==0 ) cnt++;
            cnt = Math.floor( Math.random()*cnt )
            for( tt=0; tt<(C_COL*C_ROW); tt++ ) if( field[tt]==0 ){if(cnt<=0){break;}else{cnt--;}}
            computer_move(tt%C_COL,Math.floor(tt/C_COL)); return;

        } else {
            /*** wenn schwer, dann richtig überlegen ***/
            solutions = new Array(0);
            /* zunächst sämtliche startszenarien beachten ( # leeres Feld, O Computer, X Mensch )*/
            /* 1. Fall: alles leer */
            /* # # #         O # O */
            /* # # #     =   # O # */
            /* # # #         O # O */
            cnt = 0;
            for( i=0; i<C_COL*C_ROW; i++ ) if( field[i] == 0 ) cnt++;
            if( cnt == C_COL*C_ROW )
               solutions = new Array(0,0,0,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,2,2);

            /* 2. Fall: Mensch hat irgend eine Ecke */
            /* X # #         X # # */
            /* # # #     =   # O # */
            /* # # #         # # # */
            /* 3. Fall: Mensch hat Mitte */
            /* # # #         O # O */
            /* # X #     =   # X # */
            /* # # #         O # O */
            /* 4. Fall: Mensch hat oben unten links oder rechts */
            /* # X #         # X # */
            /* X # X     =   X O X */
            /* # X #         # X # */
            cnt_0 = 0; cnt_1 = 0;
            for( i=0; i<C_COL*C_ROW; i++ ) {
                 if( field[i] == 0 ) cnt_0++;
                 if( field[i] == 1 ) cnt_1++;
            }
            if( cnt_0 == C_COL*C_ROW-1 && cnt_1 == 1 ) {
                if( field[4] == 1 ) /* Fall 3 */
                    solutions = new Array(0,0,0,2,2,0,2,2);
                if( field[0]==1 || field[2]==1 || field[6]==1 || field[8]==1) /* Fall 2 */
                    solutions = new Array(1,1);
                if( field[1]==1 || field[3]==1 || field[5]==1 || field[7]==1) /* Fall 4 */
                    solutions = new Array(1,1);
            }
            /* 5. Fall: */
            /* X # #         X O # */
            /* # O #     =   O O O */
            /* # # X         # O X */
            cnt_0 = 0; cnt_1 = 0; cnt_2 = 0;
            for( i=0; i<C_COL*C_ROW; i++ ) {
                 if( field[i] == 1 ) cnt_1++;
                 if( field[i] == 2 ) cnt_2++;
            }
            if( cnt_1 == 2 && cnt_2 == 1 ) {
                if( field[4]==2 && (  field[0]==1 && field[8]==1 || field[2]==1 && field[6]==1 ) )
                    solutions = new Array(1,0,0,1,2,1,1,2);
            }
            /* 6. Fall: */
            /* # X #         O X O */
            /* # O #     =   O O O */
            /* # # #         O # O */
            cnt_0 = 0; cnt_1 = 0; cnt_2 = 0;
            for( i=0; i<C_COL*C_ROW; i++ ) {
                 if( field[i] == 1 ) cnt_1++;
                 if( field[i] == 2 ) cnt_2++;
            }
            if( cnt_1 == 1 && cnt_2 == 1 ) {
                if( field[4]==2 ) {
                   if( field[1]==1 || field[7]==1) solutions = new Array(0,0,0,1,0,2,2,0,2,1,2,2);
                   if( field[3]==1 || field[5]==1 ) solutions = new Array(0,0,1,0,2,0,0,2,1,2,2,2);
                }
            }
            /* 7. Fall: */
            /* X O O         X O O */
            /* 0 # 0     =   O X O */
            /* 0 0 0         O O O */
            cnt_0 = 0; cnt_1 = 0; cnt_2 = 0;
            for( i=0; i<C_COL*C_ROW; i++ ) {
                 if( field[i] == 1 ) cnt_1++;
                 if( field[i] == 2 ) cnt_2++;
            }
            if( cnt_1 == 1 && cnt_2 == 1 ) {
                if( field[4]==0 ) {
                    if( field[0]==1 ) solutions = new Array(1,0,2,0,0,1,2,1,0,2,1,2,2,2);
                }
            }

            /* alle anderen Fälle durch suchen von 2 möglichen Reihen ermitteln */
            /* zunächst meine möglichen 2 reihen finden */
            if( solutions.length == 0 ) {
              lncnt1 = 0; if( count_line(0,0,1,0,1)==0 && count_line(0,0,1,0,2)==1 ) lncnt1 = 1;
              lncnt2 = 0; if( count_line(0,1,1,0,1)==0 && count_line(0,1,1,0,2)==1 ) lncnt2 = 1;
              lncnt3 = 0; if( count_line(0,2,1,0,1)==0 && count_line(0,2,1,0,2)==1 ) lncnt3 = 1;
              lncnt4 = 0; if( count_line(0,0,0,1,1)==0 && count_line(0,0,0,1,2)==1 ) lncnt4 = 1;
              lncnt5 = 0; if( count_line(1,0,0,1,1)==0 && count_line(1,0,0,1,2)==1 ) lncnt5 = 1;
              lncnt6 = 0; if( count_line(2,0,0,1,1)==0 && count_line(2,0,0,1,2)==1 ) lncnt6 = 1;
              lncnt7 = 0; if( count_line(0,2,1,-1,1)==0 && count_line(2,2,-1,-1,2)==1 ) lncnt7=1;
              lncnt8 = 0; if( count_line(0,0,1,1,1)==0 && count_line(0,0,1,1,2)==1 ) lncnt8 = 1;
              /* in der äußeren schleife alle freien felder ermitteln */
              for( i=0; i<C_COL*C_ROW; i++ ) {
                if( field[i] == 0 ) { /* leeres feld! */
                /* nun schauen ob in mind. 2 richtungen 2 reihen mit jeweils 1 freiem da sind */
                if( i==0 && (lncnt1+lncnt4+lncnt8)>1 ) solutions = solutions.concat(new Array(0,0));
                if( i==2 && (lncnt1+lncnt6+lncnt7)>1 ) solutions = solutions.concat(new Array(2,0));
                if( i==6 && (lncnt3+lncnt4+lncnt7)>1 ) solutions = solutions.concat(new Array(0,2));
                if( i==8 && (lncnt3+lncnt6+lncnt8)>1 ) solutions = solutions.concat(new Array(2,2));
                if( i==1 && (lncnt1+lncnt5)>1 ) solutions = solutions.concat(new Array(1,0));
                if( i==3 && (lncnt2+lncnt4)>1 ) solutions = solutions.concat(new Array(0,1));
                if( i==5 && (lncnt6+lncnt2)>1 ) solutions = solutions.concat(new Array(2,1));
                if( i==7 && (lncnt3+lncnt5)>1 ) solutions = solutions.concat(new Array(1,2));
                }
              }
            }

            /* jetzt die 2 möglichen reihen vom menschen finden */
            if( solutions.length == 0 ) {
              lncnt1 = 0; if( count_line(0,0,1,0,2)==0 && count_line(0,0,1,0,1)==1 ) lncnt1 = 1;
              lncnt2 = 0; if( count_line(0,1,1,0,2)==0 && count_line(0,1,1,0,1)==1 ) lncnt2 = 1;
              lncnt3 = 0; if( count_line(0,2,1,0,2)==0 && count_line(0,2,1,0,1)==1 ) lncnt3 = 1;
              lncnt4 = 0; if( count_line(0,0,0,1,2)==0 && count_line(0,0,0,1,1)==1 ) lncnt4 = 1;
              lncnt5 = 0; if( count_line(1,0,0,1,2)==0 && count_line(1,0,0,1,1)==1 ) lncnt5 = 1;
              lncnt6 = 0; if( count_line(2,0,0,1,2)==0 && count_line(2,0,0,1,1)==1 ) lncnt6 = 1;
              lncnt7 = 0; if( count_line(0,2,1,-1,2)==0 && count_line(2,2,-1,-1,1)==1 ) lncnt7=1;
              lncnt8 = 0; if( count_line(0,0,1,1,2)==0 && count_line(0,0,1,1,1)==1 ) lncnt8 = 1;
              /* in der äußeren schleife alle freien felder ermitteln */
              for( i=0; i<C_COL*C_ROW; i++ ) {
                if( field[i] == 0 ) { /* leeres feld! */
                /* nun schauen ob in mind. 2 richtungen 2 reihen mit jeweils 1 freiem da sind */
                if( i==0 && (lncnt1+lncnt4+lncnt8)>1 ) solutions = solutions.concat(new Array(0,0));
                if( i==2 && (lncnt1+lncnt6+lncnt7)>1 ) solutions = solutions.concat(new Array(2,0));
                if( i==6 && (lncnt3+lncnt4+lncnt7)>1 ) solutions = solutions.concat(new Array(0,2));
                if( i==8 && (lncnt3+lncnt6+lncnt8)>1 ) solutions = solutions.concat(new Array(2,2));
                if( i==1 && (lncnt1+lncnt5)>1 ) solutions = solutions.concat(new Array(1,0));
                if( i==3 && (lncnt2+lncnt4)>1 ) solutions = solutions.concat(new Array(0,1));
                if( i==5 && (lncnt6+lncnt2)>1 ) solutions = solutions.concat(new Array(2,1));
                if( i==7 && (lncnt3+lncnt5)>1 ) solutions = solutions.concat(new Array(1,2));
                }
              }
            }

            /* Ab hier wird aus dem Array solutions[] per Zufall eine Möglichkeit ausgewählt */
            size = solutions.length / 2; /* da immer 2 koordinaten x und y */
            if( size == 0 ) {
                /* falls solutions leer ist, dann per zufall ein freies feld besetzen */
                //alert("? setze per zufall")
                cnt=0; for( tt=0; tt<(C_COL*C_ROW); tt++ ) if( field[tt]==0 ) cnt++;

                cnt = Math.floor( Math.random()*cnt )
                for( tt=0; tt<(C_COL*C_ROW); tt++ ) if( field[tt]==0 ){if(cnt<=0){break;}else{cnt--;}}
                computer_move(tt%C_COL,Math.floor(tt/C_COL)); return;
            } else {
                pos = Math.floor( Math.random()*size )
                computer_move(solutions[2*pos],solutions[2*pos+1]); return;
            }
        }
        status=1;
}

function computer_move(x,y) {
         gsetxy(x,y,kreis);
         status = 1;
         check_win();
}

function count_line(start_x, start_y, dx, dy, stat) {
        cnt=0; xx=start_x; yy=start_y;
        for( ttt=0; ttt<C_COL; ttt++){
                if( (my_stat = readxy(xx,yy)) == -1 ) return -1;
                if( my_stat == stat ) cnt++;
                if( my_stat == 0 ) { free_x = xx; free_y = yy; }
                xx+=dx; yy+=dy;
        }
        return cnt;
}

function readxy(x,y) {
         return field[y*C_COL+x];
}

function setxy(x,y,value) {
         field[y*C_COL+x] = value;
}


/******************************************/
/*** Funktionen zur graphischen Ausgabe ***/
/******************************************/
function getimgobj(x,y) {
         /* suche x,y */
         my_offset = y * C_COL + x;
         offset = 0;
         for( ctr = 0; ctr < document.images.length; ctr++ ) {
              if( document.images[ctr].src.indexOf(leerimg) != -1 ||
                  document.images[ctr].src.indexOf(kreisimg) != -1 ||
                  document.images[ctr].src.indexOf(kreuzimg) != -1 ) {
                     if( offset >= my_offset ) return document.images[ctr];
                     offset++;
                  }
         }
         return -1;
}

function gsetxy(x,y,image) {
         getimgobj(x,y).src = image.src;
         value=0;
         if( image.src.indexOf(kreuzimg) != -1 ) value=1; /* Mansch */
         if( image.src.indexOf(kreisimg) != -1 ) value=2; /* computer */
         setxy(x,y,value)
}
