tic tac toe – Improved Tic Tac Toe game. Made in C

For my second week of learning C, I decided to remake the Tic Tac Toe game I made last week, but in a different style (as some of you recommended me). This is my final product on the whole Tic Tac Toe game idea, so I tried my best. I feel like it is a bit overkill, but I want to know your opinion.

Here is the code:

/*
 * TESTED IN LINUX - 2020
 * 
 * This is my version of Tic Tac Toe, with an expandable board.
 * The standard size for the board is 3x3,
 * but it can be changed (only editing the script for now) to a 5x5, 7x7...
 * To expand the board you need to change the first 2 sizes of the 'board' array,
 * and by changing the 'boardSqrt' var to the same value as the first two.
*/


// Including needed stuff
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#include <string.h>

// Creating the board struct
struct TTT_BoardGame {
    unsigned short playerTurn;
    int boardSqrt;
    double boardLen;
    bool canFinish;
    char board(3)(3)(3);
};

// Initializing the board struct
struct TTT_BoardGame ttt_init(void) {
    struct TTT_BoardGame game = {};
    game.playerTurn = 0;
    game.boardSqrt = 3;
    game.boardLen = game.boardSqrt * game.boardSqrt;
    game.canFinish = false;
    
    // Set the starting value in each board cell
    char pos(3) = {'0', '0', '1'};
    for (unsigned short v = 0; v < game.boardSqrt; v++) {
        for (unsigned short h = 0; h < game.boardSqrt; h++) {
        for (short p = 2; p >= 0; p--) {
            game.board(v)(h)(p) = pos(p);
        }
        if (pos(2) < '9')
                pos(2)++;
            else {
                pos(2) = '0';
                pos(1)++;
            }

            if (pos(1) > '9') {
                pos(1) = '0';
                pos(0)++;
            }
        }
    }
    return game;
}

// The menu that displays when starting the game
void ttt_startMenu(void) {
    char key;
    system("clear");
    printf("Tic tac toe game.nnTip: When prompted, each player needs to choose a spot to place their symbol.nPress the 'Enter' key to continue... ");
    scanf("%c", &key);
}

// Returns the symbol of the current player
char ttt_currentPlayerTurn(struct TTT_BoardGame *game) {
    return game->playerTurn % 2 ? 'O' : 'X';
}

// Returns the symbol of the player before the one now
char ttt_lastPlayerTurn(struct TTT_BoardGame *game) {
    return game->playerTurn % 2 ? 'X' : 'O';
}

// Asks the current player for a position
char *ttt_askForPosition(struct TTT_BoardGame *game) {
    static char pos(3);

    printf("Choose a position for '%c': ", ttt_currentPlayerTurn(game));
    scanf("%s", pos);
    
    return pos;
}

// Checks if the spot chosen by the player is empty
bool ttt_isLegalMove(struct TTT_BoardGame *game, unsigned short col, unsigned short row) {
    if ((row + 1) <= game->boardSqrt && (col +1) <= game->boardSqrt) {
        if (game->board(col)(row)(1) != 'X' && game->board(col)(row)(1) != 'O')
            return true;
    }
    return false;
}

// Edit the board cell to display the symbol of the current player
void ttt_markAnswer(struct TTT_BoardGame *game) {
    char *ans = ttt_askForPosition(game);

    for (unsigned short col = 0; col < game->boardSqrt; col++){
        for (unsigned short row = 0; row < game->boardSqrt; row++) {
        if (strncmp(ans, game->board(col)(row), 3) == 0) {
            if (ttt_isLegalMove(game, col, row)) {
                    game->board(col)(row)(0) = ' ';
                    game->board(col)(row)(2) = ' ';
                    game->board(col)(row)(1) = ttt_currentPlayerTurn(game);
                    game->playerTurn++;
            break;
                }   
                else {
                    ttt_markAnswer(game);
                }
            }
        }
    }
}

// Prints one row of board cells
void ttt_displayBoardSegment(struct TTT_BoardGame *game, unsigned short vPos) {
    for (unsigned short v = 0; v < 3; v++) {
        if (v % 2 == 0) {
            for (unsigned short h = 0; h < game->boardSqrt; h++)
                printf("|=====|");
        } else {
            for (unsigned short h = 0; h < game->boardSqrt; h++)
                printf("| %c%c%c |", game->board(vPos)(h)(0), game->board(vPos)(h)(1), game->board(vPos)(h)(2));
        }
        printf("n");
    }
}

// Prints as many board cell rows as needed
void ttt_displayBoardTotal(struct TTT_BoardGame *game) {
    system("clear");
    printf("Tic Tac Toe %dx%dnn", game->boardSqrt, game->boardSqrt);
    for (unsigned short i = 0; i < game->boardSqrt; i++)
        ttt_displayBoardSegment(game, i);
}

// Checks if the game ended in a draw
bool ttt_testForDraw(struct TTT_BoardGame *game) {
    return game->playerTurn >= game->boardLen;
}

// Checks for rows with each cell full of one symbol
bool ttt_isHorizontalWin(struct TTT_BoardGame *game) {
    for (unsigned short v = 0; v < game->boardSqrt; v++) {
        char elem = game->board(v)(0)(1);
        for (unsigned short h = 0; h < game->boardSqrt; h++) {
            if (elem != game->board(v)(h)(1))
                break;
            if (h == game->boardSqrt - 1) {
                if (elem == 'X' || elem == 'O')
                return true;
            }
        }
    }
    return false;
}

// Checks for columns with each cell full of one symbol
bool ttt_isVerticalWin(struct TTT_BoardGame *game) {
    for (unsigned short h = 0; h < game->boardSqrt; h++) {
        char elem = game->board(0)(h)(1);
        for (unsigned short v = 0; v < game->boardSqrt; v++) {
            if (elem != game->board(v)(h)(1))
                break;
            if (v == game->boardSqrt - 1) {
                if (elem == 'X' || elem == 'O')
                return true;
            }
        }
    }
    return false;
}

// Checks one diagonal (top left -> bottom right) with each cell full of one symbol 
bool ttt_isDiagonalWinLeftToRight(struct TTT_BoardGame *game) {
    char elem = game->board(0)(0)(1);

    for (unsigned short v = 0, h = 0; v < game->boardSqrt; v++, h++) {
        if (elem != game->board(v)(h)(1))
            break;
        if (h == game->boardSqrt - 1) {
            if (elem == 'X' || elem == 'O')
                return true;
        }
    }
    return false;
}

// Checks other diagonal (top right -> bottom left) with each cell full of one symbol
bool ttt_isDiagonalWinRightToLeft(struct TTT_BoardGame *game) {
    unsigned short lastPosRow = game->boardSqrt - 1;
    char elem = game->board(0)(lastPosRow)(1);

    for (unsigned short v = 0, h = game->boardSqrt - 1; v < game->boardSqrt; v++, h--) {

        if (elem != game->board(v)(h)(1))
            break;
        if (h == 0) {
            if (elem == 'X' || elem == 'O')
                return true;
        } 
    }
    return false;
}

// All of the 'win' possibilities combined
bool ttt_testForWin(struct TTT_BoardGame *game) {
    if (ttt_isVerticalWin(game) || ttt_isHorizontalWin(game) || ttt_isDiagonalWinLeftToRight(game) || ttt_isDiagonalWinRightToLeft(game))
        return true;
}

// Checks if somebody won or the game ended in a draw
bool ttt_finishGame(struct TTT_BoardGame *game) {
    if (ttt_testForWin(game) && game->canFinish) {
        printf("n'%c' won!n", ttt_lastPlayerTurn(game));
        return true;
    }
    else if (ttt_testForDraw(game) && game->canFinish) {
        printf("nDraw!n");
        return true;
    }
    else if (ttt_testForWin(game) || ttt_testForDraw(game)) {
        game->canFinish = true;
    }
    return false;
}


// 'main' function
int main() {
    ttt_startMenu();
    
    for (struct TTT_BoardGame game = ttt_init();;) {
        ttt_displayBoardTotal(&game);

        if (!game.canFinish)
            ttt_markAnswer(&game);

    if (ttt_finishGame(&game))
        break;
    }

    return 0;
}

What do you think? Can I optimize it even more?

P.S: I also made a GitHub project where I put my old game and my new one.

tic tac toe code in c++ with two players

My main problems are making draw case and any player can choose a place which is chosen by another player here is the code :

#include <iostream>
using namespace std;

char board(3)(3) = {{'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}};
static int turnnumber = 1 ;
bool winner = false, flag = false ;
bool win(){
     if(board(0)(0)==board(1)(1)&&board(1)(1)==board(2)(2))
    winner = true ;
    if(board(0)(2)==board(1)(1)&&board(1)(1)==board(2)(0))
    winner = true ;
if(board(1)(0)==board(1)(1)&&board(1)(1)==board(1)(2))
    winner = true ;
if(board(0)(0)==board(0)(1)&&board(0)(1)==board(0)(2))
    winner = true ;
if(board(2)(0)==board(2)(1)&&board(2)(1)==board(2)(2))
    winner = true ;    
if(board(0)(0)==board(1)(0)&&board(1)(0)==board(2)(0))
    winner = true ;
if(board(0)(1)==board(1)(1)&&board(1)(1)==board(2)(1))
    winner = true ;
if(board(0)(2)==board(1)(2)&&board(1)(2)==board(2)(2))
    winner = true ;
            
    if(winner==true&&turnnumber==1)
       cout << "player2 won nn" ;
    if(winner==true&&turnnumber==2)
       cout << "player1 won nn" ;
 
    return winner;
}

void view()
{
    for (int i = 0; i < 3; i++)
    {
        for (int x = 0; x < 3; x++)
        {
            cout << "(" << board(i)(x) << ")  ";
        }
        cout << endl
             << "-------------" << endl;
    }
}
    
void players()
{
    
    char player1 = 'X', player2 = 'O';
    int number;
    cout << "nplayer " << turnnumber << " it's your turn ";
    if(turnnumber==1)
       turnnumber++;
    else if(turnnumber==2)
       turnnumber--;
    char player;
    if(turnnumber==1)
       player=player2;
    if(turnnumber==2)
       player=player1;
    cin >> number ;
    
    switch(number){
        
    case 1:
        board(0)(0) = player;
        break;
    case 2:
        board(0)(1) = player;
        break;
    case 3:
        board(0)(2) = player;
        break;
    case 4:
        board(1)(0) = player;
        break;
    case 5:
        board(1)(1) = player;
        break;
    case 6:
        board(1)(2) = player;
        break;
    case 7:
        board(2)(0) = player;
        break;
    case 8:
        board(2)(1) = player;
        break;
    case 9:
        board(2)(2) = player;
        break;
    default:
        cout << "nwrong numbern";
        players();
         
    }
    system("cls");
    view();
 
    if(!win())
        players();
}

int main()
{
    view();
    players();
}

python 3.x – Smart Tic Tac Toe, a reinforcement learning approach

I’m currently familiarizing myself with reinforcement learning basics and for convenience purposes (instead of manually entering coordinates in the terminal), I created a very simple UI for testing trained agents and play games against them. You can experiment and play around with it using different hyperparameters but as this is a very basic reinforcement learning algorithm I did not get good results for boards larger than the standard tic tac toe size (3 x 3).

For using it just run python3 ui.py the agent will be trained and then the ui will be loaded and you can play against the trained agent.

Here’s how the ui looks like:

enter image description here

helper.py

import numpy as np


class TicBase:
    """
    Base class with useful utils/helpers.
    """

    def __init__(self, board_size=3, empty_value=0, x_value=2, o_value=3):
        """
        Initialize common settings.
        Args:
            board_size: int, board cell x cell size.
            empty_value: int, representation of available cells.
            x_value: int, representation(internal not for display) of X on the board.
            o_value: int, representation(internal not for display) of O on the board.
        """
        self.board_size = board_size
        self.board = np.ones((board_size, board_size)) * empty_value
        self.empty_value = empty_value
        self.x_value = x_value
        self.o_value = o_value

    def get_empty_cells(self, board=None):
        """
        Get empty locations that are available.
        Args:
            board: numpy array of shape n, n where n: self.board_size.

        Returns:
            A list of (x, y) empty indices of the board.
        """
        board = board if board is not None else self.board
        empty_locations = np.where(board == self.empty_value)
        return list(zip(empty_locations(0), empty_locations(1)))

    def check_game_ended(self, board):
        """
        Check for empty cells.
        Args:
            board: numpy array of shape n, n where n: self.board_size.

        Returns:
            True if there are empty cells, False otherwise.
        """
        return not np.any(board == self.empty_value)

    def check_win(self, symbol, board=None):
        """
        Check if there is a winner.
        Args:
            symbol: int, representation of the player on the board.
            board: numpy array of shape n, n where n: self.board_size.

        Returns:
            symbol if symbol is winner else None.
        """
        board = board if board is not None else self.board
        result = (
            np.all(board == symbol, axis=0).any()
            or np.all(board == symbol, axis=1).any()
            or np.all(board.diagonal() == symbol)
            or np.all(board(::-1).diagonal() == symbol)
        )
        if result:
            return symbol

    def reset_game(self, symbol=None):
        """
        Reset board.
        Args:
            symbol: int, representation of the winning player on the board.

        Returns:
            None
        """
        self.board = (
            np.ones((self.board_size, self.board_size)) * self.empty_value
        )

agent.py

from helper import TicBase
import numpy as np


class TicAgent(TicBase):
    """
    Tic Tac Toe agent.
    """

    def __init__(
        self, agent_settings, board_size=3, empty_value=0, x_value=2, o_value=3
    ):
        """
        Initialize agent settings.
        Args:
            agent_settings: Dictionary that has the following keys:
                - 'epsilon': float, value from 0 to 1 representing degree
                    of random(exploratory) moves.
                - 'learning_rate': float, Learning rate used to update values.
                - 'symbol': int, representation of the agent on the board.
            board_size: int, board cell x cell size.
            empty_value: int, representation of available cells.
            x_value: int, representation(internal not for display) of X on the board.
            o_value: int, representation(internal not for display) of O on the board.
        """
        TicBase.__init__(self, board_size, empty_value, x_value, o_value)
        self.symbol = agent_settings('symbol')
        self.opponent_symbol = x_value if self.symbol == o_value else o_value
        self.learning_rate = agent_settings('learning_rate')
        self.epsilon = agent_settings('epsilon')
        self.game_scores = {}

    @staticmethod
    def get_game_id(board):
        """
        Convert game to string representation for storing game scores.
        Args:
            board: numpy array of shape n, n where n: self.board_size.

        Returns:
            string representation of the game.
        """
        return ''.join(board.reshape(-1).astype(int).astype(str))

    def calculate_score(self, board):
        """
        Calculate game score which depends on the winner/loser.
        Args:
            board: numpy array of shape n, n where n: self.board_size.

        Returns:
            score.
        """
        game_id = self.get_game_id(board)
        score = self.game_scores.get(game_id)
        if score is not None:
            return score
        score = 0
        winner = self.check_win(self.symbol, board) or (
            self.check_win(self.opponent_symbol, board)
        )
        if winner == self.symbol:
            score = 1
        if not winner and not self.check_game_ended(board):
            score = 0.5
        self.game_scores(game_id) = score
        return score

    def generate_move(self, board, empty_locations, learning=True):
        """
        Generate a random/best value move according to self.epsilon.
        Args:
            board: numpy array of shape n, n where n: self.board_size which
                represents the game most-recent state.
            empty_locations: A list of (x, y) empty indices of the board.
            learning: If True, exploration is allowed.

        Returns:
            Chosen empty_locations index.
        """
        probability = np.random.rand()
        if probability < self.epsilon and learning:
            return np.random.choice(len(empty_locations))
        possible_moves = (board.copy() for _ in empty_locations)
        for idx, empty_location in enumerate(empty_locations):
            r, c = empty_location
            possible_moves(idx)(r, c) = self.symbol
        scores = (
            self.calculate_score(possible) for possible in possible_moves
        )
        return np.argmax(scores)

    def step(self, board):
        """
        Take turn.
        Args:
            board: numpy array of shape n, n where n: self.board_size which
                represents the game most-recent state.

        Returns:
            None
        """
        empty_locations = self.get_empty_cells(board)
        move_idx = self.generate_move(board, empty_locations)
        r, c = empty_locations(move_idx)
        board(r, c) = self.symbol

    def update_game_scores(self, game_history, winner):
        """
        Update agent weights.
        Args:
            game_history: A list of numpy arrays(game boards) of 1 full game.
            winner: int representation of agent/opponent.

        Returns:
            None
        """
        target = 1 if winner == self.symbol else 0
        for game in reversed(game_history):
            game_id = self.get_game_id(game)
            old_score = self.calculate_score(game)
            updated_score = old_score + self.learning_rate * (
                target - old_score
            )
            self.game_scores(game_id) = updated_score
            target = updated_score

trainer.py

from helper import TicBase
from agent import TicAgent


class TicTrainer(TicBase):
    """
    Tool for agent training.
    """

    def __init__(
        self, agent_settings, board_size=3, empty_value=0, x_value=2, o_value=3
    ):
        """
        Initialize agents for training.
        Args:
            agent_settings: A list of 2 dictionaries for 2 agents.
            board_size: int, board cell x cell size.
            empty_value: int, representation of available cells.
            x_value: int, representation(internal not for display) of X on the board.
            o_value: int, representation(internal not for display) of O on the board.
        """
        TicBase.__init__(self, board_size, empty_value, x_value, o_value)
        self.agent_1 = TicAgent(
            agent_settings(0), board_size, empty_value, x_value, o_value
        )
        self.agent_2 = TicAgent(
            agent_settings(1), board_size, empty_value, x_value, o_value
        )

    def play_one(self, game_history):
        """
        Play one game.
        Args:
            game_history: A list of numpy arrays(game boards) of 1 full game.

        Returns:
            symbol or 'end' or None.
        """
        board = self.board
        for agent in (self.agent_1, self.agent_2):
            agent.step(board)
            game_history.append(board.copy())
            if self.check_win(agent.symbol, board):
                return agent.symbol
            if self.check_game_ended(board):
                return 'end'

    def train_step(self):
        """
        1 training step/iteration and update.
        Returns:
            None
        """
        game_history = ()
        while True:
            winner = self.play_one(game_history)
            if winner in ('end', self.x_value, self.o_value):
                break
        self.agent_1.update_game_scores(game_history, winner)
        self.agent_2.update_game_scores(game_history, winner)
        self.reset_game(winner)

    def train_basic(self, iterations):
        """
        Train using the most basic value function.
        Args:
            iterations: Training loop size.

        Returns:
            self.agent_1, self.agent2
        """
        for i in range(iterations):
            percent = round((i + 1) / iterations * 100, 2)
            print(
                f'r Training agent ... iteration: '
                f'{i}/{iterations} - {percent}% completed',
                end='',
            )
            self.train_step()
        return self.agent_1, self.agent_2

ui.py

from PyQt5.QtWidgets import (
    QMainWindow,
    QDesktopWidget,
    QApplication,
    QWidget,
    QHBoxLayout,
    QVBoxLayout,
    QPushButton,
    QLabel,
)
from PyQt5.QtCore import Qt
import numpy as np
import sys
from helper import TicBase
from trainer import TicTrainer


class TicCell(QPushButton):
    """
    Tic Tac Toe cell.
    """

    def __init__(self, location):
        """
        Initialize cell location.
        Args:
            location: Tuple, (row, col).
        """
        super(QPushButton, self).__init__()
        self.location = location


class TicUI(QMainWindow, TicBase):
    """
    Tic Tac Toe interface.
    """

    def __init__(
        self,
        window_title='Smart Tic Tac Toe',
        board_size=3,
        empty_value=0,
        x_value=2,
        o_value=3,
        agent=None,
    ):
        """
        Initialize game settings.
        Args:
            window_title: Display window name.
            board_size: int, the board will be of size(board_size, board_size).
            empty_value: int representation of an empty cell.
            x_value: int representation of a cell containing X.
            o_value: int representation of a cell containing O.
            agent: Trained TicAgent object.
        """
        super(QMainWindow, self).__init__()
        TicBase.__init__(
            self,
            board_size=board_size,
            empty_value=empty_value,
            x_value=x_value,
            o_value=o_value,
        )
        self.setWindowTitle(window_title)
        self.agent = agent
        if self.agent is not None:
            self.agent.board = self.board
        self.text_map = {
            x_value: 'X',
            o_value: 'O',
            empty_value: '',
            'X': x_value,
            'O': o_value,
            '': empty_value,
        }
        win_rectangle = self.frameGeometry()
        center_point = QDesktopWidget().availableGeometry().center()
        win_rectangle.moveCenter(center_point)
        self.central_widget = QWidget(self)
        self.main_layout = QVBoxLayout()
        self.score_layout = QHBoxLayout()
        self.human_score = 0
        self.agent_score = 0
        self.score_board = QLabel()
        self.update_score_board()
        self.setStyleSheet('QPushButton:!hover {color: yellow}')
        self.cells = (
            (TicCell((c, r)) for r in range(board_size))
            for c in range(board_size)
        )
        self.cell_layouts = (QHBoxLayout() for _ in self.cells)
        self.adjust_layouts()
        self.adjust_cells()
        self.update_cell_values()
        self.show()

    def adjust_layouts(self):
        """
        Adjust score board and cell layouts.

        Returns:
            None
        """
        self.main_layout.addLayout(self.score_layout)
        for cell_layout in self.cell_layouts:
            self.main_layout.addLayout(cell_layout)
        self.central_widget.setLayout(self.main_layout)
        self.setCentralWidget(self.central_widget)

    def adjust_cells(self):
        """
        Adjust display cells.

        Returns:
            None
        """
        self.score_layout.addWidget(self.score_board)
        self.score_board.setAlignment(Qt.AlignCenter)
        for row_index, row in enumerate(self.cells):
            for cell in row:
                cell.setFixedSize(50, 50)
                cell.clicked.connect(self.game_step)
                self.cell_layouts(row_index).addWidget(cell)

    def get_empty_cells(self, board=None):
        """
        Get empty cell locations.

        Returns:
            A list of indices that represent currently empty cells.
        """
        empty_locations = super().get_empty_cells()
        for empty_location in empty_locations:
            r, c = empty_location
            cell_text = self.cells(r)(c).text()
            assert cell_text == self.text_map(self.empty_value), (
                f'location {empty_location} has a cell value of {cell_text}'
                f'and board value of {self.board(r)(c)}'
            )
        return empty_locations

    def update_score_board(self):
        """
        Update the display scores.

        Returns:
            None
        """
        self.score_board.setText(
            f'Human {self.human_score} - ' f'{self.agent_score} Agent'
        )

    def reset_cell_colors(self):
        """
        Reset display cell text colors.

        Returns:
            None
        """
        for row_idx in range(self.board_size):
            for col_idx in range(self.board_size):
                self.cells(row_idx)(col_idx).setStyleSheet('color: yellow')

    def reset_game(self, symbol=None):
        """
        Reset board and display cells and update display scores.
        Args:
            symbol: int, self.x_value or self.o_value.

        Returns:
            None
        """
        super().reset_game(symbol)
        self.update_cell_values()
        if symbol == self.x_value:
            self.human_score += 1
        if symbol == self.o_value:
            self.agent_score += 1
        self.update_score_board()
        self.reset_cell_colors()

    def modify_step(self, cell_location, value):
        """
        Modify board and display cells.
        Args:
            cell_location: tuple, representing indices(row, col).
            value: int, self.x_value or self.o_value.

        Returns:
            True if the clicked cell is not empty, None otherwise.
        """
        r, c = cell_location
        board_value = self.board(r, c)
        cell_value = self.cells(r)(c).text()
        if not board_value == self.empty_value:
            return True
        assert cell_value == self.text_map(self.empty_value), (
            f'mismatch between board value({board_value}) '
            f'and cell value({cell_value}) for location {(r, c)}'
        )
        if value == self.x_value:
            self.cells(r)(c).setStyleSheet('color: red')
        self.board(r, c) = value
        self.cells(r)(c).setText(f'{self.text_map(value)}')

    def game_step(self):
        """
        Post cell-click step(human step and agent step)

        Returns:
            None
        """
        cell = self.sender()
        stop = self.modify_step(cell.location, self.x_value)
        if stop:
            return
        x_win = self.check_win(self.x_value)
        if x_win is not None:
            self.reset_game(self.x_value)
            return
        empty_locations = self.get_empty_cells()
        if not empty_locations:
            self.reset_game()
            return
        choice = np.random.choice(len(empty_locations))
        if self.agent:
            choice = self.agent.generate_move(
                self.board, empty_locations, False
            )
        self.modify_step(empty_locations(choice), self.o_value)
        o_win = self.check_win(self.o_value)
        if o_win is not None:
            self.reset_game(self.o_value)

    def update_cell_values(self):
        """
        Sync display cells with self.board

        Returns:
            None
        """
        for row_index, row in enumerate(self.board):
            for col_index, col in enumerate(row):
                update_value = self.text_map(self.board(row_index)(col_index))
                self.cells(row_index)(col_index).setText(f'{update_value}')


if __name__ == '__main__':
    s = (
        {'symbol': 2, 'epsilon': 0.1, 'learning_rate': 0.5},
        {'symbol': 3, 'epsilon': 0.1, 'learning_rate': 0.5},
    )
    train = TicTrainer(s)
    a1, a2 = train.train_basic(10000)
    test = QApplication(sys.argv)
    window = TicUI(agent=a2)
    sys.exit(test.exec_())

javascript – Almost unbeatable Tic Tac Toe

JavaScript beginner here! I have written a Tic Tac Toe game is JS that seems to be unbeatable (Title says ‘almost’ because I’m not sure if it’s really unbeatable or just I can’t beat it 🙂 ).
I really appreciate any help to improve my code and learn from my mistakes.
Project’s CodePen = https://codepen.io/MiladM1715/full/ZEQOLmZ

    // Tic Tac Toe Win figures
var gameCtrl = (function () {
  var winningConditions, corners, randomCorner;
  winningConditions = (
    (3, 4, 5),
    (2, 4, 6),
    (0, 4, 8),
    (0, 1, 2),
    (6, 7, 8),
    (0, 3, 6),
    (1, 4, 7),
    (2, 5, 8),
  );

  corners = (0, 2, 6, 8);
  randomCorner = corners(Math.floor(Math.random() * 4));

  //   If win possible? Win! if not? Block
  function winOrBlock(arr, marker, winCondition) {
    var status;
    // Count number of founded markers (first user & then opponent) if more the two, win or block
    var count = 0;
    if (arr(0) === marker) count++;
    if (arr(1) === marker) count++;
    if (arr(2) === marker) count++;
    if (count >= 2 && arr.includes("")) {
      // Return empty marker to use
      if (arr(0) === "") status = winCondition(0);
      if (arr(1) === "") status = winCondition(1);
      if (arr(2) === "") status = winCondition(2);
      return status;
    }
  }
  // Don't put marker somewhere that there's no chance to win
  function noStupidMove(arr, marker, winCondition) {
    var checkCorners;
    var count = 0;
    if (arr(0) === '') count++;
    if (arr(1) === '') count++;
    if (arr(2) === '') count++;
    if (arr.includes(marker) && count > 1) {
      return winCondition(arr.indexOf(""));
    }
  }
  // If none of others work
  function neturalMove(arr, marker, winCondition) {
    //   If win figures include marker, and there
    if(arr.includes(marker) && arr.includes('')) {
      return winCondition(arr.indexOf(""));
    }
  }

  //Function to add moves id to game board structure
  return {
    addToBoard: function (id, marker, board) {
      board(id) = marker;
    },

    // Works for first and 2nd move
    firstMoves: function (board, counter, moves) {
      var result;
      //   after opponent's first move, if Center is empty, place it in center, If not? random corner
      if (counter === 1) {
        return board(4) === "" ? 4 : randomCorner;
      } else {
        //   If it's opponent's second move, check moves array and decide. If none of conditions met, then return false and let winOrBlock or neturalMove do it's job
        if (moves(0) === 0 && moves(1) === 7) result = 6;
        if (moves(0) === 6 && moves(1) === 5) result = 1;
        if (moves(0) === 4 && moves(1) === 8) result = 2;
        if (moves(0) === 4 && moves(1) === 2) result = 8;
        return board(result) === "" ? result : false;
      }
    },

    // Check if there is a chance for win, block or netural move || check win too
    checkStatus: function (board, type, marker, counter) {
      var a, b, c, winCondition, callback, check, opMarker;

      // Set oponet marker based on currnt marker
      marker === "O" ? (opMarker = "X") : (opMarker = "O");

      if (type === "check" && counter !== 0) {
        // Call functions based on stategy 1.win 2.block 3.netural
        callback = (
          (winOrBlock, marker),
          (winOrBlock, opMarker),
          (noStupidMove, marker),
          (neturalMove, marker),
        );
      } else if (type === "check" && counter === 0) {
        return randomCorner;
      } else if (type === "win") {
        callback = "1";
      }

      for (var x = 0; x < callback.length; x++) {
        for (var i = 0; i < winningConditions.length; i++) {
          winCondition = winningConditions(i);
          a = board(winCondition(0));
          b = board(winCondition(1));
          c = board(winCondition(2));

          //   Check win or place number?
          if (type === "check") {
            check = callback(x)(0)((a, b, c), callback(x)(1), winCondition);
            if (check || check === 0) {
              return check;
            }
            // if check 'type' is "win" only check for win
          } else if (type === "win") {
            //   If a,b,c are same and not empty then it's a win
            if (a === b && b === c && c !== "") {
              return true;
            }
          }
        }
      }
    },
    // If there is no empty cell, it's a draw (called after win check)
    isDraw: function (board) {
      return !board.includes("");
    },
  };
})();

// Takes care of UI
var UICtrl = (function () {

  return {

    DOMstrings: {
      startBtn: '.start-btn',
      userScore: '.sc-',
      gameResult: '.result',
      finalMsg: '.msg',
      gameCells: '.cells',
      gameCell: '.cell',
    },

    clearUI: function () {
      var cells, cellArr;
      cells = document.querySelectorAll(this.DOMstrings.gameCell);
      cellArr = Array.prototype.slice.call(cells);
      cellArr.forEach(function (cur) {
        cur.textContent = "";
      });
    },
    // Add marker to UI
    addMarkerUI: function (id, marker) {
      var color;
      marker === "X" ? (color = "black") : (color = "white");
      document.getElementById(
        id
      ).innerHTML = `<span style="color: ${color}">${marker}</span>`;
    },

    // disable start btn afte start and Enable it after draw or win
    disableStartBtn: function (state) {
      document.querySelector(this.DOMstrings.startBtn).disabled = state;
    },

    // Display score on UI
    displayScore: function (player, score) {
      document.querySelector(this.DOMstrings.userScore + player).textContent = score(player);
    },

    // display Win or Draw result
    displayResult: function (win, draw, player) {
      var msg, resultDiv;
      player === 0 ? (player = "YOU WIN!") : (player = "YOU LOSE!");
      if (win) msg = player;
      if (draw) msg = "DRAW";
      resultDiv = document.querySelector(this.DOMstrings.gameResult);
      resultDiv.style.display = "flex";
      document.querySelector(this.DOMstrings.finalMsg).textContent = msg;
      setTimeout(function () {
        resultDiv.style.display = "none";
      }, 2000);
    },
  };
})();

// Control game behavior
var controll = (function () {
  var gameBoard,
    isActive,
    playerMarker,
    currentPlayer,
    score,
    counter,
    twoMoveArr,
    DOM;
  gameBoard = ("", "", "", "", "", "", "", "", "");
  isActive = true;
  playerMarker = ("X", "O");
  currentPlayer = 0;
  score = (0, 0);
  twoMoveArr = ();
  counter = 0;
  whoIsPlayingFirst = 0;
  DOM = UICtrl.DOMstrings;

  // Game Start
  document.querySelector(DOM.startBtn).addEventListener("click", function () {
    // 1.hide start btn
    UICtrl.disableStartBtn(true);

    // 2 Reset game UI
    UICtrl.clearUI();

    // 3 Active game
    isActive = true;

    // 4. Decide who's playing first
    changePlayer();
  });

  // changes player after hitting start btn and invokes functions
  function changePlayer() {
    whoIsPlayingFirst === 1 ? (whoIsPlayingFirst = 0) : (whoIsPlayingFirst = 1);
    whoIsPlayingFirst === 1 ? userPlay() : AIplay();
  }

  function userPlay() {
    document.querySelector(DOM.gameCells).addEventListener("click", function (e) {
      // Works only if clicked cell is empty and game is active
      if (isActive && e.target.textContent === "") {
        // 1. Get clicked cell and set marker
        var cellID = parseInt(e.target.id);
        var marker = playerMarker(0);

        //   Add Selected cell to board and UI
        handleDataUI(cellID, marker, gameBoard);

        // increase counter to findout play count
        counter++;
        // Push first two moves into an array to use it later fo blocking
        counter < 2 ? twoMoveArr.push(cellID) : (twoMoveArr = false);

        // Check for Win or Draw
        var win, draw;
        win = resultChecker(score, currentPlayer);
        draw = resultChecker(score, currentPlayer);
        if (!win && !draw) {
          AIplay();
        }
      }
    });
  }

  function AIplay() {
    //   Change player id to 1
    currentPlayer = 1;
    // Set Marker
    marker = playerMarker(1);
    // If User plays first
    if (whoIsPlayingFirst === 1) {
      // check for first and second moves
      firstTwo = gameCtrl.firstMoves(gameBoard, counter, twoMoveArr);
      if (counter < 3 && typeof firstTwo === "number") {
        cellID = firstTwo;
      } else {
        //   If itsn't two first moves or it returned False, Try to win, block or netural move
        cellID = gameCtrl.checkStatus(gameBoard, "check", marker, counter);
      }
      //   If AI plays first, if it's first move then, place marker on random corner. if not first move then try to win or block or do netural move
    } else {
      cellID = gameCtrl.checkStatus(gameBoard, "check", marker, counter);
    }
    // Add it to Data strucure and UI
    handleDataUI(cellID, marker, gameBoard);
    // Check result
    resultChecker(score, currentPlayer);
    currentPlayer = 0;
  }

//   adds moves to data and UI
  function handleDataUI(id, marker, board) {
    gameCtrl.addToBoard(id, marker, board);
    UICtrl.addMarkerUI(id, marker);
  }

//   Checks for win and draw
  function resultChecker(score, currentPlayer) {
    var win = gameCtrl.checkStatus(gameBoard, "win");
    var draw = gameCtrl.isDraw(gameBoard);
    if (win) {
      score(currentPlayer) += 1;
      UICtrl.displayScore(currentPlayer, score);
      UICtrl.displayResult(win, false, currentPlayer);
      resetGame();
      return true;
    }
    if (draw) {
      UICtrl.displayResult(false, draw, currentPlayer);
      resetGame();
      return true;
    }
    return false;
  }

//   Resets game after every game
  function resetGame() {
    document.querySelector(DOM.startBtn).textContent = "Play Again";
    gameBoard = ("", "", "", "", "", "", "", "", "");
    currentPlayer = 0;
    isActive = false;
    counter = 0;
    twoMoveArr = ();
    // Enables start btn
    UICtrl.disableStartBtn(false);
  }

  return {
    init: function () {
      UICtrl.clearUI();
    },
  };
})(gameCtrl, UICtrl);

controll.init();

Checking if naughts or crosses win in Tic Tac Toe

I am working on a coding challenge for Tic Tac Toe. I am calculating the results and inserting them into the database.

However I have a long and messy if statement, which checks if the array’s values match a valid win for O or X.
I feel like it could be refactored down but I’m unsure on how to approach this.

    /** @var int */
protected $xWins = 0;

/** @var int */
protected $oWins = 0;

/** @var int */
protected $draws = 0;

/**
 */
public function __construct()
{
    // creates a new database on object creation
    $this->database = new Database();
}

    public function winner(string $input)
    {
        $input = str_replace("\n", "", $input);

        $length = strlen($input);

        for ($i = 1; $i <= $length; $i++) {
            if ($i % 9 === 0) {

                $result = substr($input, $i - 9, 9);

                if ($result(0) === "X" && $result(1) === "X" && $result(2) === "X") {
                    $winner = "X";
                    $this->database->insert($winner, $result);
                    $this->xWins++;
                } else if ($result(3) === "X" && $result(4) === "X" && $result(5) === "X") {
                    $winner = "x";
                    $this->database->insert($winner, $result);
                    $this->xWins++;
                } else if ($result(6) === "X" && $result(7) === "X" && $result(8) === "X") {
                    $winner = "X";
                    $this->database->insert($winner, $result);
                    $this->xWins++;
                } else if ($result(0) === "X" && $result(3) === "X" && $result(6) === "X") {
                    $winner = "X";
                    $this->database->insert($winner, $result);
                    $this->xWins++;
                } else if ($result(1) === "X" && $result(4) === "X" && $result(7) === "X") {
                    $winner = "X";
                    $this->database->insert($winner, $result);
                    $this->xWins++;
                } else if ($result(2) === "X" && $result(5) === "X" && $result(8) === "X") {
                    $winner = "X";
                    $this->database->insert($winner, $result);
                    $this->xWins++;
                } else if ($result(0) === "X" && $result(4) === "X" && $result(8) === "X") {
                    $winner = "X";
                    $this->database->insert($winner, $result);
                    $this->xWins++;
                } else if ($result(2) === "X" && $result(4) === "X" && $result(6) === "X") {
                    $winner = "X";
                    $this->database->insert($winner, $result);
                    $this->xWins++;
                }

                // checks for O lines
                else if ($result(0) === "O" && $result(1) === "O" && $result(2) === "O") {
                    $winner = "o";
                    $this->database->insert($winner, $result);
                    $this->oWins++;;
                } else if ($result(3) === "O" && $result(4) === "O" && $result(5) === "O") {
                    $winner = "o";
                    $this->database->insert($winner, $result);
                    $this->oWins++;
                } else if ($result(6) === "O" && $result(7) === "O" && $result(8) === "O") {
                    $winner = "o";
                    $this->database->insert($winner, $result);
                    $this->oWins++;
                } else if ($result(0) === "O" && $result(3) === "O" && $result(6) === "O") {
                    $winner = "o";
                    $this->database->insert($winner, $result);
                    $this->oWins++;
                } else if ($result(1) === "O" && $result(4) === "O" && $result(7) === "O") {
                    $winner = "O";
                    $this->database->insert($winner, $result);
                    $this->oWins++;
                } else if ($result(2) === "O" && $result(5) === "O" && $result(8) === "O") {
                    $winner = "O";
                    $this->database->insert($winner, $result);
                    $this->oWins++;
                } else if ($result(0) === "O" && $result(4) === "O" && $result(8) === "O") {
                    $winner = "O";
                    $this->database->insert($winner, $result);
                    $this->oWins++;
                } else if ($result(2) === "O" && $result(4) === "O" && $result(6) === "O") {
                    $winner = "O";
                    $this->database->insert($winner, $result);
                    $this->oWins++;
                    // checks for draw
                } else {
                    $winner = "Draw";
                    $this->database->insert($winner, $result);
                    $this->draws++;
                }
            }
        }

Python Tic Tac Toe Building Block Function

Would appreciate any input on these building blocks functions of tic tac toe.

def display_field(cells):
    print('''
---------
| {} {} {} |
| {} {} {} |
| {} {} {} |
---------
'''.format(*cells))


def analyze_field(cells):
    """

    Args:
        cells (str): a string of an XO pattern

    Returns:
        (str): the result of the XO field
    """

    num_x = cells.lower().count('x')
    num_o = cells.lower().count('o')

    rows = ((cells(j) for j in range(i, i + 3)) for i in range(0, 9, 3))
    columns = ((row(i) for row in rows) for i in range(3))

    first_diagonal = rows(0)(0) + rows(1)(1) + rows(2)(2)
    second_diagonal = rows(0)(2) + rows(1)(1) + rows(2)(0)

    if abs(num_x - num_o) not in (0, 1):
        return 'Impossible'

    num_winners = 0
    for row, column in zip(rows, columns):
        if len(set(row)) == 1:
            num_winners += 1
        if len(set(column)) == 1:
            num_winners += 1
    if num_winners > 1:
        return 'Impossible'

    for row in rows:
        if len(set(row)) <= 1:
            return f'{row(0)} wins'

    for column in columns:
        if len(set(column)) <= 1:
            return f'{column(0)} wins'

    if len(set(first_diagonal)) <= 1:
        return f'{first_diagonal(0)} wins'

    elif len(set(second_diagonal)) <= 1:
        return f'{second_diagonal(0)} wins'

    # No winner
    else:
        if '_' in cells or ' ' in cells:
            return 'Game not finished'
        else:
            return 'Draw'


cells = input('Enter cells:')

display_field(cells)

print(analyze_field(cells))

Enter cells:XO_XO_XOX
---------
| X O _ |
| X O _ |
| X O X |
---------
Impossible

python 3.x – Tic Tac Toe with aacii art

I have written a simple tictactoe game using some ascii art. It is what I can do to improve the logic and structure of the program. Thank you.

"""A basic command line tic tac toe game"""
import os
import sys

gameBoard       = (('' for j in range(3)) for i in range(3))
displayBoard    = ((' ' for j in range(46)) for i in range(25))

def main():
    """Main method to control game"""
    player = 'X'#Player x to go first
    moveCounter = 1 #Keeps track of how many turns have been taken

    #Setup game
    initGame()
    printInitScreen()

    while True:
        #Get player input
        square = input(f"Player {player}, choose your square ->")

        if validateInput(square):
            updateGameBoard(square, player)
            updateDisplayBoard(square, player)
            printDisplayBoard()

            if moveCounter >= 4:
                checkIfWon(player)

            #Switch player
            if player == 'X':
                player = 'O'
            else:
                player = 'X'

            moveCounter += 1

        else:
            print("Please try again")

def initGame():
    """Create and set up game components"""

    #Fill board
    for i in range(25):
        #If on a row boarder set to _
        if i == 8 or i == 17:
            for j in range(46):
                displayBoard(i)(j) = '_'
        else:
            for j in range(46):
                #If on column boarder set |
                if j == 15 or j == 31:
                    displayBoard(i)(j) = '|'

    #Put numbers in corner of square
    displayBoard(0)(0)   = '1'
    displayBoard(0)(16)  = '2'
    displayBoard(0)(32)  = '3'
    displayBoard(9)(0)   = '4'
    displayBoard(9)(16)  = '5'
    displayBoard(9)(32)  = '6'
    displayBoard(18)(0)  = '7'
    displayBoard(18)(16) = '8'
    displayBoard(18)(32) = '9'


def validateInput(input):
    """Validates user input"""
    #Check given char is allowed
    try:
        square = int(input(0)) #Check first char of input is number
    except:
        return False

    #Check nothing already in that square
    #Get the gameBoard index of users chosen square
    index = numToIndex(input)
    if gameBoard(index(0))(index(1)) != '':
        return False

    #If all ok
    return True

def updateGameBoard(input, player):
    """Keeps track of users moves"""
    #Update the array with new move
    index = numToIndex(input(0))
    gameBoard(index(0))(index(1)) = player

def printDisplayBoard():
    """Prints a string representation of board"""
    os.system('cls' if os.name == 'nt' else 'clear')  # Clear screen

    for row in displayBoard:
        print(''.join(row))

    print("")

def checkIfWon(player):
    """Checks to see if the last move won the game"""
    gameWon = False
    #Check Horiz
    for row in gameBoard:
        if row(0) == row(1) == row(2) == player:
            gameWon = True

    #Check Vert
    for i in range(3):
        if gameBoard(0)(i) == gameBoard(1)(i) == gameBoard(2)(i) == player:
            gameWon = True

    #Check Diag
    if gameBoard(0)(0) == gameBoard(1)(1) == gameBoard(2)(2) == player:
        gameWon = True
    if gameBoard(0)(2) == gameBoard(1)(1) == gameBoard(2)(0) == player:
        gameWon = True

    if gameWon:
        print(f"Congratualtions player {player}, you won!")
        sys.exit()

def printGameBoard():
    """For debugging, prints gameboard"""
    for row in gameBoard:
        print(row)

def printInitScreen():
    """Prints the initial welcome screen"""
    header = """
    888   d8b        888                   888
    888   Y8P        888                   888
    888              888                   888
    888888888 .d8888b888888 8888b.  .d8888b888888 .d88b.  .d88b.
    888   888d88P"   888       "88bd88P"   888   d88""88bd8P  Y8b
    888   888888     888   .d888888888     888   888  88888888888
    Y88b. 888Y88b.   Y88b. 888  888Y88b.   Y88b. Y88..88PY8b.
     "Y888888 "Y8888P "Y888"Y888888 "Y8888P "Y888 "Y88P"  "Y8888
    """
    os.system('cls' if os.name == 'nt' else 'clear')  # Clear screen
    print(header)
    input("Press enter to start!")
    printDisplayBoard()

def updateDisplayBoard(num, player):
    """Add the players shape to the chosen position on display board"""
    shapes = {"X":
              ((' ',' ',' ',' ','?','8','8','8','8','P',' ',' ',' ',' '),
               (' ',' ',' ',' ',' ','`','8','8','`',' ',' ',' ',' ',' '),
               ('8','b',',','_',' ',' ','8','8',' ',' ','_',',','d','8'),
               ('8','8','8','8','8','S','I','C','K','8','8','8','8','8'),
               ('8','P','~',' ',' ',' ','8','8',' ',' ',' ','~','?','8'),
               (' ',' ',' ',' ',' ',',','8','8','.',' ',' ',' ',' ',' '),
               (' ',' ',' ',' ','d','8','8','8','8','b',' ',' ',' ',' ')),
               "O":
              ((' ',' ',' ',' ',' ',' ','%','%',' ',' ',' ',' ',' ',' '),
               (' ',' ',' ',' ','%','%',' ',' ','%','%',' ',' ',' ',' '),
               (' ',' ','%','%',' ',' ',' ',' ',' ',' ','%','%',' ',' '),
               ('%','%',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','%','%'),
               (' ',' ','%','%',' ',' ',' ',' ',' ',' ','%','%',' ',' '),
               (' ',' ',' ',' ','%','%',' ',' ','%','%',' ',' ',' ',' '),
               (' ',' ',' ',' ',' ',' ','%','%',' ',' ',' ',' ',' ',' '))}

    shape = shapes(player)
    num = int(num(0))

    offsets = ((0 ,0),(0 ,16),(0 ,32),
               (9 ,0),(9 ,16),(9 ,32),
               (17,0),(17,16),(17,32))

    iOffset = offsets(num-1)(0)
    jOffset = offsets(num-1)(1)

    for i in range(iOffset, iOffset + 7):
        for j in range(jOffset, jOffset + 14):
            displayBoard(i+1)(j) = shape(i - iOffset)(j - jOffset)

def numToIndex(num):
    """Returns index (i,j) for given 'square' on board"""
    num = int(num(0))
    indexList = ()
    for i in range (3):
        for j in range(3):
            indexList.append((i,j))

    return indexList(int(num)-1)

if __name__ == '__main__':
    main()

```

python – Tic Tac Toe using the Cartesian coordinate system

I'm trying to learn the Cartesian Coordinate System, starting with a basic three-in-one grid for simplicity, and then perhaps moving on to chess. I was able to do the following code to get started:

board = ()

def new_board():
    for row in range(4):
        board.append(())
        for column in range(4):
            board(row).append('_')

def print_board():
    print(board)
    print('  %s | %s | %s' % (board(1)(1), board(1)(2), board(1)(3)))
    print('----+---+----')
    print('  %s | %s | %s' % (board(2)(1), board(2)(2), board(2)(3)))
    print('----+---+----')
    print('  %s | %s | %s' % (board(3)(1), board(3)(2), board(3)(3)))

new_board()
print(board)
print_board()

When the list & # 39; dashboard & # 39; is printed, it gives the following:

(('_', '_', '_', '_'), ('_', '_', '_', '_'), ('_', '_', '_', '_'), ('_', '_', '_', '_'))
(('_', '_', '_', '_'), ('_', '_', '_', '_'), ('_', '_', '_', '_'), ('_', '_', '_', '_'))

Which is fine, but my problem is that in order for my commands to match the dash (for example dash (1) (2) directed to the first row and second column of the dash), I have to have a & # 39 ; dummy entry & # 39; for (0), both for the sublists and for the entries in the sublists.

Is there a way to do this without the dummy entries and still my board list references match the actual board spaces?

tic tac toe written in c #

my first project in c # (I already code in python, so any help to migrate to c # is appreciated)
I had a little problem with 2d arrays vs. irregular arrays, but nothing a little SO can't fix

using System;
using System.Linq;
namespace take2
{
    class maine
    {
        const char X = 'X';
        const char O = 'O';
        static char()() board;
        static void Clear()
        {
            board = new char()() { new char() { '1', '2', '3' }, new char() { '4', '5', '6' }, new char() { '7', '8', '9' } };
        }
        static void Draw()
        {
            for (int y = 0; y < 3; y++)
            {
                Console.WriteLine(String.Format("{0} {1} {2}", board(y)(0), board(y)(1), board(y)(2)));
            }
        }
        static char CheckWin()
        {
            string() cases =
            {
                new String(board(0)),
                new String(board(1)),
                new String(board(2)),
                new String(new char(){board(0)(0),board(1)(0),board(2)(0)}),
                new String(new char(){board(0)(1),board(1)(1),board(2)(1)}),
                new String(new char(){board(0)(2),board(1)(2),board(2)(2)}),
                new String(new char(){board(0)(0),board(1)(1),board(2)(2)}),
                new String(new char(){board(0)(2),board(1)(1),board(2)(0)}),
            };
            if (cases.Contains(new string(X, 3)))
            {
                return X;
            }
            else if (cases.Contains(new string(X, 3)))
            {
                return O;
            }
            else
            {
                return 'N';
            }

        }
        static void Main()
        {
            char player;
            string play = null;
            while (play != "N")
            {
                Clear();
                Draw();
                for (int turn = 1; turn <= 9; turn++)
                {
                    //x's turn

                    player = turn % 2 == 0 ? player = O : player = X;

                    /*string choice = Console.ReadLine();
                    int x = (int)(Math.Floor((decimal.Parse(choice) - 1) % 3));
                    int y = (int)((double.Parse(choice)- 1- x) / 3);
                                   */
                    int x = 0;
                    int y = 0;
                    string choice="";
                    bool occupied = true;
                    short tryParse = 1337;
                    bool parsable = false;
                    while (occupied)
                    {
                        while((!parsable) || tryParse>9 || tryParse<1)
                        {

                            Console.WriteLine(string.Format("{0}'s turn", player));
                            choice = Console.ReadLine();
                            parsable = Int16.TryParse(choice, out tryParse);
                        }
                        x = (int)(Math.Floor((decimal.Parse(choice) - 1) % 3));
                        y = (int)((double.Parse(choice) - 1 - x) / 3);
                        occupied = (board(y)(x) == X) || (board(y)(x) == O);
                        parsable = false;
                    }
                    board(y)(x) = player;

                    Console.Clear();
                    Draw();
                    if (CheckWin() != 'N')
                    {
                        Console.WriteLine(String.Format("{0} wins", CheckWin()));
                        break;
                    }

                }
                Console.WriteLine("play again? (Y)es / (N)o");
                play = Console.ReadLine();
                Console.Clear();
            }
        }
    }
}
```

game – Tic Tac Toe in C ++ (console version)

I have made a Tic Tac Toe game for 2 players in C ++
I also put some verification errors (like if players enter an invalid position)

#include 
using namespace std;

#define Player1 1
#define Player2 2

int whoseTurn;

string moves(3) = {"empty", "cross", "zero"};
string board(9) = {"empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty"};
//An array to avoid duplicate input
int playedPos(9) = {0};

void printBoard()
{
    cout << endl;
    for (int i = 0; i < 9; i++)
    {
        if (i == 3 || i == 6)
        {
            cout << endl;
            cout << endl;
        }
        if (board(i) == "empty")
        {
            cout << "t"
                 << " | ";
        }
        else
        {
            cout << "t" << board(i) << " ";
        }
    }
    cout << endl;
}

//Checking if any paper has won
bool check_for_victory(string board())
{
    if ((board(0) != "empty") && (board(0) == board(1)) && (board(1) == board(2)))
        return true;
    if ((board(3) != "empty") && (board(3) == board(4)) && (board(4) == board(5)))
        return true;
    if ((board(6) != "empty") && (board(6) == board(7)) && (board(7) == board(8)))
        return true;
    if ((board(0) != "empty") && (board(0) == board(3)) && (board(3) == board(6)))
        return true;
    if ((board(1) != "empty") && (board(1) == board(4)) && (board(4) == board(7)))
        return true;
    if ((board(2) != "empty") && (board(2) == board(5)) && (board(5) == board(8)))
        return true;
    if ((board(0) != "empty") && (board(0) == board(4)) && (board(4) == board(8)))
        return true;
    if ((board(6) != "empty") && (board(6) == board(4)) && (board(4) == board(2)))
        return true;
    return false;
}

void makeMove(int whoseTurn)
{
    //Variable for counting how many times the game is played
    int gameCount = 0;
    int pos, move;
    while ((check_for_victory(board) == false) && (gameCount != 9))
    {
        cout << "Where you want to make move: ";
        cin >> pos;
        if (pos < 10 && pos > 0) //Checking if the user entered a valid move
        {
            pos--;
            //incrementing the position at the pos index to 1
            playedPos(pos)++;
            if (playedPos(pos) <= 1)
            {
                if (whoseTurn == Player1)
                {
                    move = Player1;
                    board(pos) = moves(move);
                    printBoard();
                    whoseTurn = Player2;
                    gameCount++;
                }
                else if (whoseTurn == Player2)
                {
                    move = Player2;
                    board(pos) = moves(move);
                    printBoard();
                    whoseTurn = Player1;
                    gameCount++;
                }
            }
            else
            {
                cout << "You have played this move" << endl;
            }
        }
        else
        {
            cout << "Enter a valid position" << endl;
        }
    }

    if ((check_for_victory(board) == false) && gameCount != 9)
    {
        cout << "Math is draw" << endl;
    }
    else
    {
        if (whoseTurn == Player1)
        {
            cout << "Player 2 is WINNER!" << endl;
        }
        else
        {
            cout << "Player 1 is WINNNER!" << endl;
        }
    }
}

int main()
{
    whoseTurn = Player1;
    printBoard();
    makeMove(Player1);
}