2016-11-16 52 views
0

/*連接4遊戲板的程序目前作爲下面的代碼。源代碼將初始玩家表示爲在第二位玩家的移動之後增加1的奇數,該數字在偶數下注明。當對角線方向上有四個連續的奇數或偶數時,我不確定如何讓它檢測到勝利。這個問題可能源於在winflag中使用「if(iswin())」和「winflag = true」永遠不會被視爲真實,但是,我不確定。 */連接4 - C++:無法獲取程序以確定是否發生對角線贏

#include <iostream> 

    using namespace std; 

/*global constants and variables; 
*/ 


    const int H = 6; 

    const int W = 7; 

    int height = H; 

    int width = W; 

int colstatus[W]; // 1-D keeps tracking which row will be next available spot for each col. 

int board[H][W]; // 2-D array 

int steps = 0; 

int lastcol; 

bool winflag = false; 

int neighbourrowpos; 

int neighbourcolpos; 

// function prototypes 

int whichside(int, int); 

void initialize(); 

bool islegal(int, int); 

bool play(); 

bool iswin(); 

void showgame(); 

int main(); 

// implementation of functions 

bool islegal(int row, int col) 
{ 
    if (row<0 || row >= H || col<0 || col>W) return false; // out of boundary of the board. 
    else 
     return true; 
} 

int whichside(int row, int col) 
{ 
    if (board[row][col] == 0) return 0; // means a spot is open 

    if (board[row][col] % 2) return 1; // means odd side 
    else return -1; // means even side 

} 

bool iswin() 
{ 
    int counter = 1; 
    int lastrow; 
    lastrow = colstatus[lastcol] + 1; // based on the next available one to determine the row of the last move. 

             // vertically, the board should be checked solely in a downward direction, not upward 
    neighbourrowpos = lastrow + 1; // the first one right after the last move. 
    neighbourcolpos = lastcol; 

    while (islegal(neighbourrowpos, neighbourcolpos)) 
    { 
     //if the stone at nextposition is on the same side of the last drop. 
     if (whichside(neighbourrowpos, neighbourcolpos) == whichside(colstatus[lastcol] + 1, lastcol)) 
     { 
      counter++; 
      if (counter == 4) return true; // win 
      else 
       neighbourrowpos++; // ++ to go down 
     } 
     else 
      return false; // no win occurs due to the encounter of of another side before reaching 4. 
    } 


    // check horizontally, both left and right 
    counter = 1; // resets counter to 1 from the last move to check horizontal 
       //check left first.  
    neighbourrowpos = lastrow; 
    neighbourcolpos = lastcol - 1; 
    while (islegal(neighbourrowpos, neighbourcolpos)) 
    { 
     if (whichside(neighbourrowpos, neighbourcolpos) == whichside(lastrow, lastcol)) 
     { 
      counter++; 
      if (counter == 4) return true; // win 
      else 
       neighbourcolpos--; //-- to go left 
     } 
     else 
      break; // too early to return false because the right side may contribute too. The loop should have a break so as to permit the user to continue testing on the right side. 

    } 
    // the program will continue to perform a check on the right wing from the previous move. 
    neighbourcolpos = lastcol + 1; 
    while (islegal(neighbourrowpos, neighbourcolpos)) 
    { 
     if (whichside(neighbourrowpos, neighbourcolpos) == whichside(lastrow, lastcol)) 
     { 
      counter++; 
      if (counter == 4) return true; // win 
      else 
       neighbourcolpos++; //++ to go right 
     } 
     else 
      return false; // when the program has been checked on its left and right sides and meet a different side before reaching 4, which signifies that it can return. 

    } 

    //in this stance, the program should check diagonally topleft to bottomright. once more, ensure that two segments are symmetric with respect to the previous move. 
    neighbourrowpos = lastcol; 
    neighbourcolpos = lastrow - 1; 
    while (islegal(neighbourrowpos, neighbourcolpos)) 
    { 
     if (whichside(neighbourrowpos, neighbourcolpos) == whichside(lastrow, lastcol)) 
     { 
      counter++; 
      if (counter == 4) return true; //win 
      else 
       neighbourcolpos--; //-- to shift to the left 
     } 
     else 
      return false; 
    } 

    neighbourcolpos = lastrow + 1; 
    while (islegal(neighbourrowpos, neighbourcolpos)) 
    { 
     if (whichside(neighbourrowpos, neighbourcolpos) == whichside(lastrow, lastcol)) 
     { 
      counter++; 
      if (counter == 4) return true; // winner 
      else 
       neighbourcolpos++; //++ to shift to the right 
     } 
     else return false; 
    } 

    counter = 1; 
    neighbourrowpos = lastrow - 1; 
    neighbourcolpos = lastcol - 1; 

    neighbourrowpos = lastrow + 1; 
    neighbourcolpos = lastcol + 1; 

    //check diagonally top-right to bottomleft 
    counter = 1; 
    neighbourrowpos = lastrow + 1;  //conducts a check on the lower left portion of the board 
    neighbourcolpos = lastcol - 1; 

    neighbourrowpos = lastrow - 1;  //performs a check on the upper right segment of the board 
    neighbourcolpos = lastcol + 1; 

     return false; 

} 

bool play() 
{ 
    cout << "Input column number (0-6): "; 
    cin >> lastcol; 

    if (lastcol<0 || lastcol >= W) return false; 

    if (colstatus[lastcol] > -1) 
    { 
     board[colstatus[lastcol]][lastcol] = ++steps; // increase step by 1 to maintain counter of the amount of moves. Step has been initialized at zero. 
     colstatus[lastcol]--; 

     showgame(); 

     if (iswin()) //This may be the issue, however, am not certain 
      winflag = true; 

     return true; 
    } 
    else 
    { 
     return false; 
    } 

} 

void initialize() 
{ 
    for (int col = 0; col<W; col++) 
     colstatus[col] = H - 1; 

    for (int row = 0; row<H; row++) 
     for (int col = 0; col<W; col++) 
      board[row][col] = 0; 
} 
void showgame() 
{ 

    for (int row = 0; row < H; row++) 
    { 
     for (int col = 0; col < W; col++) 
      cout << board[row][col] << "\t"; 
     cout << endl; 
    } 

    cout << "---------------------------------------------" << endl; 
    for (int col = 0; col<W; col++) 
     cout << colstatus[col] << "\t"; 
    cout << endl; 

} 



int main() 
{ 
    initialize(); 
    showgame(); 

    do 
    { 
     do { 
      bool f = play(); // call play until it is true; 
      if (f == false) 
       cout << "You pick a wrong column. Please try again"; 
      else 
       break; // if it is a legal move, check winflag 
     } while (true); 

     if (winflag == true) 
     { 
      cout << whichside(colstatus[lastcol] + 1, lastcol) << " win!" << endl; // -1 even side, 1 odd side 

      break; 
     } 

     else 
     { 
      // something must be included here but am not certain on the specific statement 

     } 
    } while (true); 

    return 0; 

} 
+0

歡迎來到Stack Overflow!請[編輯]你的代碼,這是你的問題[mcve],然後我們可以嘗試重現並解決它。如果你的問題在'iswin()'中,那麼你只需要這個函數和一個調用'iswin()'的main()'給出錯誤答案的位置。遊戲的其餘部分是無關緊要的,阻礙了你回答你的問題。你還應該閱讀[問]。 –

回答

0

這只是一個一般的建議,如何爲您在連接四連勝。考慮有4種方式可以獲勝:水平,垂直,左對角線和右對角線。你可以迭代整個棋盤,並在每個包含遊戲塊的單元格中進行廣度優先搜索。這實際上需要是4種版本的搜索,每種方式都可以獲得。所有搜索的另一個約束:只考慮包含相同類型遊戲塊的單元格。搜索時要記錄走過的步數。一旦你成功地走了4步,就會有勝利。這也假定您將使用一些數據結構進行週期檢測。

這就是說,對角線版本的搜索將只考慮其各自角落的單元格。例如,起始單元格(2,1)的左對角線搜索將考慮以下內容:[(1, 2), (3, 0)],假設(0, 0)是董事會的左上角。