0% found this document useful (0 votes)
26 views4 pages

PROJEKAT

The document describes a Tic-Tac-Toe game implemented in C++. It defines classes for the game board, players, and game logic. The game can be played between a human player and AI player that uses minimax search to select moves.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views4 pages

PROJEKAT

The document describes a Tic-Tac-Toe game implemented in C++. It defines classes for the game board, players, and game logic. The game can be played between a human player and AI player that uses minimax search to select moves.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

#include <iostream>

#include <array>
#include <vector>
#include <algorithm>
#include <ctime>
#include <limits> // Added for numeric_limits

enum GameState : int


{
Running,
Draw,
Win
};

enum Symbol : char


{
Tic = 'X',
Tac = 'O',
Space = ' '
};

class TicTacToe
{
public:
std::array<Symbol, 9> board;

TicTacToe() {
[Link](Symbol::Space);
}

void print_board() const {


for (int i = 0; i < 9; ++i) {
if (i % 3)
std::cout << " | ";
std::cout << static_cast<char>(board[i]);
if (i == 2 || i == 5)
std::cout << "\n---------\n";
}
std::cout << "\n\n";
}

static Symbol swap(const Symbol symbol) {


return symbol == Symbol::Tic ? Symbol::Tac : Symbol::Tic;
}

GameState evalState(const Symbol symbol) {


if (match(symbol, 0, 1, 2) || match(symbol, 3, 4, 5) || match(symbol, 6, 7,
8) || // Horizontal checks
match(symbol, 0, 3, 6) || match(symbol, 1, 4, 7) || match(symbol, 2, 5,
8) || // Vertical Checks
match(symbol, 0, 4, 8) || match(symbol, 2, 4, 6)) // Diagonal Checks
return GameState::Win;
if (std::count([Link](), [Link](), Symbol::Space) == 0)
return GameState::Draw;
return GameState::Running;
}

private:
bool match(const Symbol symbol, int i1, int i2, int i3) {
return board[i1] == symbol && board[i2] == symbol && board[i3] == symbol;
}
};

class Player
{
public:
std::string name;
virtual int getMove(TicTacToe&, const Symbol) = 0;
};

class PlayerHuman : public Player


{
public:
virtual int getMove(TicTacToe& game, const Symbol symbol) override {
int move = -1;
while (move == -1) {
std::cout << "Enter your move for " << static_cast<char>(symbol) << "
(1-9)\n";
std::cin >> move;
if (!std::[Link]()) {
std::[Link]();
std::[Link](std::numeric_limits<std::streamsize>::max(), '\n');
}
--move;
if (move < 0 || move > 8 || [Link][move] != Symbol::Space) {
std::cerr << "Invalid input\n\n";
move = -1;
}
}
return move;
};
};

class PlayerAI : public Player


{
public:
char maxDepth = 10;
virtual int getMove(TicTacToe& game, const Symbol symbol) override {
std::cout << "AI thinking for " << static_cast<char>(symbol) << "\n";
// select random move if board is empty
if (std::count([Link](), [Link](), Symbol::Space) == 9)
return std::rand() % 9;
// calculate best move with minimax
int bestScore = -1000;
std::vector<char> moves;
for (char i = 0; i < 9; i++) {
if ([Link][i] == Symbol::Space) {
[Link][i] = symbol;
char score = minimax(game, 0, false, symbol);
if (score > bestScore) {
bestScore = score;
[Link]();
}
if (score == bestScore)
moves.push_back(i);
[Link][i] = Symbol::Space;
}
}
return moves[std::rand() % [Link]()];

protected:
int minimax(TicTacToe& game, int depth, bool isMax, const Symbol symbol) {
Symbol opponent = TicTacToe::swap(symbol);
GameState state = [Link](symbol);
if (state == GameState::Win)
return 10 - depth;
if ([Link](opponent) == GameState::Win)
return -10 + depth;
if (state == GameState::Draw || depth >= maxDepth)
return 0;
int best = isMax ? -1000 : 1000;
for (char i = 0; i < 9; i++) {
if ([Link][i] == Symbol::Space) {
[Link][i] = isMax ? symbol : opponent;
int score = minimax(game, depth + 1, !isMax, symbol);
best = isMax ? std::max(best, score) : std::min(best, score);
[Link][i] = Symbol::Space;
}
}
return best;
}
};

class Game
{
private:
TicTacToe game;

public:
void Play(Player& player1, Player& player2) {
int index = std::rand() % 2;
Symbol symbol = Symbol::Tic;

GameState state = GameState::Running;


while (state == GameState::Running) {
Player& player = index ? player1 : player2;

game.print_board();
int move = [Link](game, symbol);

std::cout << [Link] << " selected " << move + 1 << "\n\n";
[Link][move] = symbol;

state = [Link](symbol);
if (state != GameState::Running) {
game.print_board();
if (state == GameState::Win)
std::cout << [Link] << " Won!";
else
std::cout << "It's a Draw.";
}
else
{
index = !index;
symbol = TicTacToe::swap(symbol);
}
}
}
};

int main() {
std::srand(static_cast<unsigned int>(time(0)));

PlayerHuman player1;
[Link] = "human";

PlayerAI player2;
[Link] = "AI";

Game game;
[Link](player1, player2);
}

You might also like