2013-12-16 37 views
0

對於tic tac toe遊戲,我有一個Board類,它將遊戲板存儲在二維數組中。現在我正在處理項目的AI部分,我想我需要保留Board類中的未佔用單元列表或在AIPlayer類中生成列表。但是,由於我使用的是二維數組,我不確定如何去做這件事。如何存儲或生成2d索引列表

這樣做的最好方法是什麼?

這裏是我的主板類: 頭文件:

#pragma once // include guard 
#include <iostream> 

class Board 
{ 
    public: 
     Board(); 
     void displayBoard() const; 
     char getCell(int row, int column) const; 
     void setCell(int row, int column, char player); 
     bool isWon(char token) const; 
     bool isDraw()const; 

    private: 
     char board[3][3]; 
     int occupiedCells; 
}; 

實現文件:

#include "Board.h" 
#include <iostream> 

Board::Board() 
{ 
    occupiedCells = 0; 
    for (int row = 0; row < 3; row++) 
    { 
     for (int column = 0; column < 3; column++) 
      board[row][column] = ' '; 
    } 
} 

void Board::displayBoard() const 
{ 
    std::cout << "\n-------------" << std::endl; 

    for (int row = 0; row < 3; row++) 
    { 
     std::cout << "| " ; 
     for (int column = 0; column < 3; column++) 
      std::cout << board[row][column] << " | "; 
     std::cout << "\n-------------" << std::endl; 
    } 
} 

char Board::getCell(int row, int column) const 
{ 
    return board[row][column]; 
} 

void Board::setCell(int row, int column, char player) 
{ 
    board[row][column] = player; 
    occupiedCells ++; 
} 

bool Board::isWon(char token) const 
{ 
    // Check rows 
    for (int i = 0; i < 3; i++) 
     if (token == board[i] [0] && token == board[i] [1] && token == board[i] [2]) return true; 

    // Check columns 
    for (int j = 0; j < 3; j++) 
     if (token == board[0] [j] && token == board[1] [j] && token == board[2] [j]) return true; 

    // Check diagonals 
    if (token == board[0] [0] && token == board[1] [1] && token == board[2] [2]) return true; 

    if (token == board[0] [2] && token == board[1] [1] && token == board[2] [0]) return true; 

    return false; 
} 

bool Board::isDraw() const 
{ 
    if (occupiedCells == 9) 
    { 
     return true; 
    } 
    return false; 
} 

這裏是我的AIPlayer類: 頭文件:

#pragma once // include guard 
#include "Player.h" 

class AIPlayer: public Player 
{ 
    public: 
     AIPlayer(char token); 
     virtual void makeAMove(Board &myBoard); 
}; 

實施文件:

#include <stdlib.h> // rand, srand 
#include <time.h> // time 
#include "AIPlayer.h" 

AIPlayer::AIPlayer(char token) : Player(token) 
{ 
} 

void AIPlayer::makeAMove(Board &myBoard) 
{ 
    int row; 
    int column; 
    srand (time(0));  

    bool done = false; 
    do 
    { 
     row = rand() % 3; 
     column = rand() % 3; 

     if (myBoard.getCell(row, column) == ' ') 
     { 
      myBoard.setCell(row, column, getToken()); 
      done = true; 
     } 
    } 
    while (!done); 

    std::cout << "\nComputer move (" << getToken() << ")\n" 
        "row " << row << ", column " << column; 
} 
+1

我只想與指數一個數字爲0到8,並用'x = n%3'和'y = n/3'轉換爲xy。然後相反,'n =(y * 3)+ x'。 –

回答

0

有幾種方法可以解決這個問題。

如果我是你,不想創建Cellint rowint columnbool unoccupied成員,那麼我可能會嘗試一個map< pair<int, int>, bool>其中pair是行和列和bool是,它是否被佔用不。這對我來說似乎是一個簡單易讀的方法。

+0

這可能不是最好的辦法,但它確實足夠用於嘀嘀咕咕。 – caps

0

您可以將is_unoccupied函數添加到您的Board類。並通過板循環:

bool Board::is_unoccupied(int x, int y) 
{ 
    return board[x][y] == ''; // I strongly recommend you use integers instead of chars for your board. 
           // Your life will be easier, trust me. 
} 

添加一個簡單的結構,以您的代碼:

struct cell 
{ 
    cell(x, y):row(x), column(y){} 
    int row, column; 
} 

最後你可以添加返回無人居住細胞的功能:

std::list<cell> Board::unoccupied_cells() 
{ 
    std::list unoccupied; 

    for (int i=0, i<3, i++) 
     for (int j=0, j<3, j++) 
      if (is_unoccupied(i,j)) 
        unoccupied.push_back(cell(i,j)); 
    return unoccupied; 
}