1. 程式人生 > >UVa220 演算法競賽入門經典(第2版)習題4-3 黑白棋 Othello

UVa220 演算法競賽入門經典(第2版)習題4-3 黑白棋 Othello

 老規則   題目解釋看他們的  程式碼看我的。。

        可能我的程式碼略微濃縮一些。  。。

。。我找了半天,,程式碼寫的都好長。,要是看懂了題目的話 就看我的程式碼吧。

http://blog.csdn.net/kyoma/article/details/51824912

 要是看不懂程式碼的話  可以先看下面這個  然後回頭再看我這個自己亂搞的。。。

http://bbs.csdn.net/topics/391995414

 主要是 實現重複的過程  函式的多次利用。

//current 記錄的當前的顏色 W or B。  從主函式開始看 我有引導。

   #include<stdio.h>
char board[10][10];
char current;
int chuli(int x,int y,int stepx,int stepy){
     int i=0;
     while (1) {
        i++;
        x += stepx;
        y += stepy;
        if (x<1 || x>9 || y<1 || y>9) break; //貌似是沒用的廢話,習慣了。。加上邊界。
        if (board[x][y]==current && i!=1) return 1; // 如果走了一步就出現一樣的 說明兩個一樣的挨著 非法。
        if (board[x][y]!=current && board[x][y]!='-') continue;
          else  break;
     }
    return 0;
}  // 一步一步的走啊 直到出現curren一樣的停止     回到main吧
int bracketed(int x,int y){
     for (int i=-1;i<=1;i++)
       for (int j=-1;j<=1;j++){
            if (i==0 && j==0) continue;
            if (chuli(x,y,i,j)) return 1;
       }  //這裡腦洞有點大在當前點有8個 方向需要判斷 任何一個成立 都是合法位置。  轉到chuli(處理 函式)


     return 0;
  }
void change(int x,int y,int stepx,int stepy){
      board[x][y] = current;
      while (1) {
         x+=stepx;
         y+=stepy;
         if (board[x][y]==current) break;
         if (current=='B') board[x][y]='B';
             else board[x][y]='W';
      }
  } 看懂了chuli 函式 這個沒啥區別 只不過改變一下好了  道理比 chuli函式還簡單。chuli就是判斷一下 這個就翻轉一下。 回main吧
int main(){
   int T,first=1;
   scanf("%d\n",&T);
   while (T--) {
      first?first=0:putchar(10);
      for (int i=1;i<=8;i++)
         for (int j=1;j<=8;j++)
      if (j==8) {
         scanf("%c",&board[i][j]);
         getchar();
      } else scanf("%c",&board[i][j]);
      scanf("%c\n",&current);
      char ch;
      while (scanf("%c\n",&ch)){
        if (ch=='Q') {
            for (int i=1;i<=8;i++)
                for (int j=1;j<=8;j++)
                 if (j==8) printf("%c\n",board[i][j]);
            else printf("%c",board[i][j]);
            break;
        }     // 輸出結果 不解釋了吧。
        if (ch=='L'){
            int ff=1;
            for (int i=1;i<=8;i++)
                for (int j=1;j<=8;j++)
                    if (board[i][j]=='-' && bracketed(i,j)) {//  bracked 函式來判斷這個位置是否合法位置 轉到上面的函式繼續分析。
                ff?ff=0:putchar(' ');
                printf("(%d,%d)",i,j);
            }
            ff?printf("No legal move.\n"):putchar(10);
        }   
        if (ch=='M') {
                 int x,y;
                scanf("%1d%1d",&x,&y);  //  讀入數字 一個位置一個位置的讀入啊 兩個10以內的數字 之間沒有空格。
                if (!bracketed(x,y))   // 巧妙借用上一個函式,判斷是否可以放  不可的話 換下棋的一方。
                     if (current=='W') current = 'B';else current='W';
           for (int i=-1;i<=1;i++)
             for (int j=-1;j<=1;j++)
               if (i==0 && j==0) continue;
               else if (chuli(x,y,i,j)) change(x,y,i,j);  //  換過以後就可以了啊。 再次用這個chuli函式。老樣子 8個方向來找 看哪個方向可以 就去change棋盤。 轉到change


            if (current=='W') current = 'B';else current='W';
            int black=0,white=0;
            for (int i=1;i<=9;i++)
             for (int j=1;j<=9;j++){
                 if (board[i][j]=='B') black++;
                 if (board[i][j]=='W') white++;
             }
            printf("Black - %2d White - %2d\n",black,white);  // 最後了  TM大坑啊。。兩位寬度。。。。。
        }
      }
 }
}