在C ++中实现Tic-Tac-Toe的Minimax算法

时间:2014-12-14 13:34:44

标签: c++ tic-tac-toe minimax

我一直致力于Tic-Tac-Toe Minimax AI的C ++实现,我正努力迫使AI发挥阻止玩家获胜的动作。我希望有些人可以通过找出如何强制执行来帮助我。

节点代码

void Node::addToNodeList(int turn) {
  childNodes.push_back(Node(G));
  for (auto& child : childNodes) {
    child.addToNodeList(-turn);

    if (child.childNodes.empty()) {
      float tempScore = child.determineMinimaxValue();

      if (tempScore < score) {
        score = tempScore;
      }
    } else {
      for (int i = 0; i < child.childNodes.size(); i++) {
        if (child.childNodes[i].score < score) {
          score = child.childNodes[i].score;
        }
      }
    }
  }
}

float Node::determineMinimaxValue()
{
  if (childNodes.empty()) {
    if (G.getWinner() == 0) {
      return 0.f;
    } else if (G.getWinner() == -1) {
      return -1.f;
    } else if (G.getWinner() == 1) {
      return 1.f;
    }
  } else {
    for (auto& child : childNodes) {
      child.determineMinimaxValue();
    }
  }
  return 0;
}

AI播放器代码

Node AIPlayer::minimaxMove(int player, GameBoard GB)
{
  G = GB;
  N = Node(G); 
  N.addToNodeList(player);
  return N;
}

int AIPlayer::makeTheMove(GameBoard *GB, Node ND)
{
  float smallest = 100;
  for (unsigned int i = 0; i < ND.childNodes.size(); i++) {
    smallest = std::min(smallest, ND.childNodes[i].score);

    if (i == ND.childNodes.size() - 1) {
      for (unsigned int j = 0; j < ND.childNodes.size(); j++) {
        if (smallest == ND.childNodes[j].score) {
          for (int x = 0; x < 3; x++) {
            for (int y = 0; y < 3; y++) {
              for (int z = 0; z < 3; z++) {
                GB->playerBox[x][y][z] = ND.childNodes[j].G.playerBox[x][y][z];
                GB->winCondition[x][y][z] = ND.childNodes[j].G.winCondition[x][y][z];
              }
            }
          }
        }
      }
    }
  }
return 1;
}

1 个答案:

答案 0 :(得分:0)

通过使用导师的一些帮助和一些自由使用for (auto &child : childNodes)

来管理以获得答案

节点代码

void Node::addToNodeList(int turn) {
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
      //for (int k = 0; k < 3; k++) {
        if (G.playerBox[i][j][1] == 0) {
          G.playerBox[i][j][1] = turn;
          G.winCondition[i][j][1] = true;

          childNodes.push_back(Node(G));

          G.playerBox[i][j][1] = 0;
          G.winCondition[i][j][1] = false;
        }
      //}
    }
  }

for (auto &child : childNodes) {
  child.addToNodeList(-turn);

  if (child.childNodes.empty()) {
    int tempScore = child.determineMinimaxValue();

    if (tempScore < score) {
      score = tempScore;
    }
  }
  else {
    if (turn == -1) {
      int smallest = 100000;
      for (unsigned int i = 0; i < this->childNodes.size(); i++) {
        smallest = std::min(smallest, this->childNodes[i].score);
      }
      score = smallest;
    }
    else {
      int biggest = -100000;
      for (unsigned int i = 0; i < this->childNodes.size(); i++) {
        biggest = std::max(biggest, this->childNodes[i].score);
      }
    score = biggest;
    }
  }
}

int Node::determineMinimaxValue() {
  if (G.getWinner() == 0) {
    return 0;
  }
  else if (G.getWinner() == -1) {
    return -1;
  }
  else if (G.getWinner() == 1) {
    return 1;
  }
  else {
    return 0;
  }
}

AI播放器代码

Node AIPlayer::minimaxMove(int player, GameBoard GB) {
  G = GB;
  N = Node(G); 
  N.addToNodeList(player);
  return N;
}

int AIPlayer::makeTheMove(GameBoard *GB, Node ND) {
  if (GB->getWinner() == 1 || GB->getWinner() == -1) {
    return 1;
  }

  int smallest = 100000;

  for (unsigned int i = 0; i < ND.childNodes.size(); i++) {
    smallest = std::min(smallest, ND.childNodes[i].score);
  }

  for (unsigned int j = 0; j < ND.childNodes.size(); j++) {
    if (smallest == ND.childNodes[j].score) {
      for (int x = 0; x < 3; x++) {
        for (int y = 0; y < 3; y++) {
          for (int z = 0; z < 3; z++) {
            GB->playerBox[x][y][z] = ND.childNodes[j].G.playerBox[x][y][z];
            GB->winCondition[x][y][z] = ND.childNodes[j].G.winCondition[x][y][z];
          }
        }
      }
    }
  }
  return 1;
}