如何存储或生成2d索引列表

时间:2013-12-16 19:37:35

标签: c++ arrays

对于一个tic tac toe游戏,我有一个Board类,它以二维数组存储游戏板。既然我正在研究项目的AI部分,我想我需要在Board类中保留一个未占用的单元列表,或者在AIPlayer类中生成列表。但是,由于我使用的是二维阵列,我不确定如何解决这个问题。

这样做的最佳方法是什么?

这是我的董事会课程: 头文件:

#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;
}

2 个答案:

答案 0 :(得分:0)

有几种方法可以解决这个问题。

如果我是你并且不想与Cellint rowint column成员创建bool unoccupied课程,那么我可能会尝试{{1其中map< pair<int, int>, bool>是行和列,pair是否被占用。对我来说,这似乎是一种简单易读的方法。

答案 1 :(得分: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;
}