简体   繁体   English

带有链接列表C ++的井字游戏

[英]Tic-tac-toe game with Linked List C++

In one of the c++ books that I am reading, I came across one exercise that proposes me to do a tic-tac-toe game using both linked list and arrays. 在我正在阅读的一本C ++书中,我遇到了一个练习,该练习建议我使用链接列表和数组来做井字游戏。 I decided to try with linked list first, since with arrays is obviously easier. 我决定先尝试使用链表,因为使用数组显然更容易。 However, I got stuck on how to check if someone won the game. 但是,我陷入了如何检查是否有人赢得比赛的困境。 Here's what I have so far: 这是我到目前为止的内容:

struct board
{
    bool square, circle, empty;
    int pos;
    board* next;
};
void startGame(int first, board* fullBoard);
board* getBoard(board* fullBoard);


int main()
{
    int dice, first;

    board* fullBoard = NULL;
    cout << "Welcome to Tic-tac-toe DOS Game. (2 Player version)\n\n";
    cout << "X is Player 1 and O is Player 2.\nI will decide who is starting in the first match...\n ";
    srand(time(NULL));
    dice = 1;//rand() % 6 + 1;
    cout << dice;
    if(dice <= 3)
    {
        first = 1;
        cout << "Player 1 is the first!\n";
    }
    else
    {
        first = 2;
        cout << "Player 2 is the first!\n\n";
    }
    system("pause");
    system("cls");
    startGame(first, fullBoard);
}

void startGame(int first, board* fullBoard)
{
    int choice;
    bool isPlaying;
    for(int i = 1; i <= 9; i++)
        fullBoard = getBoard(fullBoard);

    bool isGameOn = true;
    while(isGameOn == true)
    {
        board* current = fullBoard;
        while(current != NULL)
        {
            if(current->empty == true)
                cout << "   " << current->pos;
            else if(current->circle == true)
                cout << "   " << "O";
            else
                cout << "   " << "X";
            if( current->pos == 4 || current->pos == 7)
            {
                cout << "\n";
                cout << "-----------------------\n";
            }
            else if (current->pos == 1)
                cout << "\n";
            else
                cout << "   |";
            current = current->next;
        }



        if(first == 1)
        {
            isPlaying = true;
            while(isPlaying == true)
            {
                cout << "Player 1, please put the number corresponding to the area you want to fill: ";
                cin >> choice;
                while(choice < 1 || choice > 9)
                {
                    cout << "Invalid choice. Please choose a valid option: ";
                    cin >> choice;
                }
                current = fullBoard;
                while(current != NULL && current->pos != choice)
                    current = current->next;

                if(current->empty == true)
                {
                    current->empty = false;
                    current->square = true;
                    isPlaying = false;
                    first = 2;
                }
                else
                    cout << "The field that you chose is already used...\n";
            }

        }
        else
        {
            isPlaying = true;
            while(isPlaying == true)
            {
                cout << "Player 2, please put the number corresponding to the area you want to fill: ";
                cin >> choice;
                while(choice < 1 || choice > 9)
                {
                    cout << "Invalid choice. Please choose a valid option: ";
                    cin >> choice;
                }
                current = fullBoard;
                while(current != NULL && current->pos != choice)
                    current = current->next;

                if(current->empty == true)
                {
                    current->empty = false;
                    current->circle = true;
                    isPlaying = false;
                    first = 1;
                }
                else
                    cout << "The field that you chose is already used...\n";
            }
        }

        system("cls");
    }


}

board* getBoard(board* fullBoard)
{
    board* newBoard = new board;
    newBoard->empty = true;
    newBoard->circle = false;
    newBoard->square = false;
    newBoard->next = fullBoard;
    if(newBoard->next != NULL)
        newBoard->pos = newBoard->next->pos + 1;
    else
        newBoard->pos = 1;
    return newBoard;


}

As you can see, on my struct Board, I have an int called pos, which I created to keep track of the whole board. 如您所见,在我的结构板上,我有一个名为pos的int,它是为了跟踪整个板而创建的。 The only solution that I can imagine so far, is checking every single position. 到目前为止,我唯一能想到的解决方案就是检查每个位置。 Ex: compare pos 8 with pos 9, 7, 5 and 2, compare pos 9 with pos 8, 7, 6, 3, 5 and 1. But I think that is way too extensive (and maybe it's hard coding as well?). 例如:比较pos 8与pos 9、7、5和2,比较pos 9与pos 8、7、6、3、5和1。但是我认为这太广泛了(也许也很难编码?) 。 What other options do you think I have? 您认为我还有其他选择吗?

Thanks in advance, Felipe 在此先感谢Felipe

I need more space to explain the "multiple lists" concept. 我需要更多空间来解释“多个列表”的概念。

Your board: 您的董事会:

 _ _ _
|_|_|_|
|_|_|_|
|_|_|_|

The lists that represent the possible solutions 代表可能解决方案的列表

D1  A B C  D2
    _ _ _
 E |_|_|_|
 F |_|_|_|
 G |_|_|_|

Note that each cell will be in at least 2 lists. 请注意,每个单元格将至少包含2个列表。

Option 1) 选项1)

You store those lists in a single "list of lists". 您可以将这些列表存储在单个“列表列表”中。 When a move is done, you iterate that list of lists, and, for each sublist (which would be A, B, etc. from the previous figure), you iterate the cells. 移动完成后,您将迭代该列表列表,然后对每个子列表(上图中为A,B等)进行迭代。 If all the cells in a sublist are from the player who moved, you found a winner. 如果子列表中的所有单元格都来自移动的玩家,则您找到了赢家。

Option 2) 选项2)

Each cell has a member that is a "list of lists". 每个单元都有一个作为“列表列表”的成员。 That "list of lists" holds the lists to check when a move is done in that cell (for example, for cell 1, you would have lists A, E and D1). 该“列表列表”保存列表以检查何时在该单元格中完成移动(例如,对于单元格1,您将具有列表A,E和D1)。 When a move is done in a cell, you get that list from the cell and check the sublists to see if you got a winner (it is more or less the same than option 1, but limiting the lists that you have to iterate over each time). 在某个单元格中完成移动后,您可以从该单元格中获取该列表,然后检查子列表以查看是否有获胜者(它与选项1大致相同,但限制了您必须遍历每个列表的列表时间)。

Note that in all the cases, we are dealing only with lists (if you add the "pointer to diagonal" and similar the structure no longer is a list). 请注意,在所有情况下,我们仅处理列表(如果您将“对角线指针添加”,类似的结构将不再是列表)。 Only that: 只有这样:

  • there are many lists. 有很多清单。
  • there are lists of cells, and lists of lists of cells. 有单元格列表和单元格列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM