Question

In: Computer Science

PLEASE READ VERY CAREFULLY write a client.py and server.py file for tic-tac-toe IN PYTHON with the...

PLEASE READ VERY CAREFULLY

write a client.py and server.py file for tic-tac-toe IN PYTHON with the following restrictions (SO WRITE TWO FILES THAT PLAY PYTHON THROUGH A SOCKET)


Use a 5 x 5 grid (dimensions are subject to change, so use constants for NUM_ROWS and NUM_COLS)


Use 'X' for player 1 and 'O' for player 2 (symbols and the number of players is subject to change, so use constants)


Each player can make 1 move per turn before having to wait for the next player to move. If an illegal move is made, an
error message is sent to the player by the server and the player loses the current turn

SO AGAIN TO RECAP A TIC TAC TOE PROGRAM IN PYTHON THAT ALLOWS TWO PLAYERS TO PLAY TOGETHER, a client and a server file

the end result will include coding similar to this

HOST = '127.0.0.1'
PORT = 12345
NUM_CONNECTIONS = 1

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(NUM_CONNECTIONS)

Solutions

Expert Solution

Gui Scipt: ttt_gui.py

# Import the GUI library Tkinter
import tkinter
# Import the messagebox module explicitly
from tkinter import messagebox
# Import the webbroswer module for opening a link
import webbrowser
# Import the client module
from ttt_client import TTTClientGame
# Import multi-threading module
import threading
# Import socket
import socket

# Constants 
C_WINDOW_WIDTH = 640;
C_WINDOW_HEIGHT = 480;
C_WINDOW_MIN_WIDTH = 480;
C_WINDOW_MIN_HEIGHT = 360;
C_COLOR_BLUE_LIGHT = "#e4f1fe";
C_COLOR_BLUE_DARK = "#304e62";
C_COLOR_BLUE = "#a8d4f2";

class CanvasWidget:
        """(Abstract) The base class for all the canvas widgets."""

        __count = 0; # Count the number of widgets initialized

        def __init__(self, canvas):
                """Initializes the widget."""
                self.canvas = canvas;
                # Generate a unique id for each widget (for tags)
                self.id = str(CanvasWidget.__count);
                CanvasWidget.__count = CanvasWidget.__count + 1;
                # Generate a unique tag for each widget
                self.tag_name = self.__class__.__name__ + self.id;
                # Initialize instance variables
                self.__disabled__ = False;
                # Set default colors
                self.normal_color = C_COLOR_BLUE; 
                self.hovered_color = C_COLOR_BLUE_DARK;

        def set_clickable(self, clickable):
                """Sets if the widget can be clicked."""
                if(clickable):
                        self.canvas.tag_bind(self.tag_name, "<Button-1>", 
                                self.__on_click__);
                else:
                        self.canvas.tag_unbind(self.tag_name, "<Button-1>");

        def __on_click__(self, event):
                """(Private) This function will be called when the user clicks on 
                the widget."""
                if(self.__disabled__):
                        return False;
                if self.command is not None:
                        self.command();
                        return True;
                else:
                        print("Error: " + self.__class__.__name__ + " " + 
                                self.id + " does not have a command");
                        raise AttributeError;
                return False;

        def set_hoverable(self, hoverable):
                """Sets if the widget can be hovered."""
                if(hoverable):
                        self.canvas.tag_bind(self.tag_name, "<Enter>", 
                                self.__on_enter__);
                        self.canvas.tag_bind(self.tag_name, "<Leave>", 
                                self.__on_leave__);
                else:
                        self.canvas.tag_unbind(self.tag_name, "<Enter>");
                        self.canvas.tag_unbind(self.tag_name, "<Leave>");

        def __on_enter__(self, event):
                """(Private) This function will be called when the mouse enters
                into the widget."""
                if(self.__disabled__):
                        return False;
                self.canvas.itemconfig(self.tag_name, fill=self.hovered_color);
                return True;

        def __on_leave__(self, event):
                """(Private) This function will be called when the mouse leaves
                the widget."""
                if(self.__disabled__):
                        return False;
                self.canvas.itemconfig(self.tag_name, fill=self.normal_color);
                return True;

        def disable(self):
                """Disables the widget so it won't respond to any events."""
                self.__disabled__ = True;

        def enable(self):
                """Enables the widget so it starts to respond to events."""
                self.__disabled__ = False;

        def is_enabled(self):
                """Returns True if the widget is disabled."""
                return self.__disabled__;

        def config(self, **kwargs):
                """Configures the widget's options."""
                return self.canvas.itemconfig(self.tag_name, **kwargs);

        def delete(self):
                self.canvas.delete(self.tag_name);

class CanvasClickableLabel(CanvasWidget):
        """A clickable label that shows text and can respond to user 
        click events."""

        def __init__(self, canvas, x, y, label_text, normal_color, 
                hovered_color):
                """Initializes the clickable label object."""

                # Initialize super class
                CanvasWidget.__init__(self, canvas);

                # Set color scheme for different states
                self.normal_color = normal_color;
                self.hovered_color = hovered_color;
                
                # Create the clickable label text
                canvas.create_text(x, y, font="Helvetica 14 underline", 
                        text=label_text, fill=self.normal_color, tags=(self.tag_name));
                
                # Bind events
                self.set_hoverable(True);
                self.set_clickable(True);

class CanvasButton(CanvasWidget):
        """A button that responds to mouse clicks."""

        # Define constant width and height
        WIDTH = 196;
        HEIGHT = 32;

        def __init__(self, canvas, x, y, button_text, normal_color, 
                hovered_color, normal_text_color, hovered_text_color):
                """Initialize the button object."""

                # Initialize super class
                CanvasWidget.__init__(self, canvas);

                # Set color scheme for different states
                self.normal_color = normal_color;
                self.hovered_color = hovered_color;
                self.normal_text_color = normal_text_color;
                self.hovered_text_color = hovered_text_color;

                # Create the rectangle background
                canvas.create_rectangle(x - self.WIDTH/2 + self.HEIGHT/2, 
                        y - self.HEIGHT/2, x + self.WIDTH/2 - self.HEIGHT/2, 
                        y + self.HEIGHT/2, fill=self.normal_color, outline="", 
                        tags=(self.tag_name, "rect" + self.id));

                # Create the two circles on both sides to create a rounded edge
                canvas.create_oval(x - self.WIDTH/2, y - self.HEIGHT/2, 
                        x - self.WIDTH/2 + self.HEIGHT, y + self.HEIGHT/2, 
                        fill=self.normal_color, outline="", 
                        tags=(self.tag_name, "oval_l" + self.id));

                canvas.create_oval(x + self.WIDTH/2 - self.HEIGHT, 
                        y - self.HEIGHT/2, x + self.WIDTH/2, y + self.HEIGHT/2,
                        fill=self.normal_color, outline="", 
                        tags=(self.tag_name, "oval_r" + self.id));

                # Create the button text
                canvas.create_text(x, y, font="Helvetica 16 bold", 
                        text=button_text, fill=self.normal_text_color, 
                        tags=(self.tag_name, "text" + self.id));

                # Bind events
                self.set_hoverable(True);
                self.set_clickable(True);

        def __on_enter__(self, event):
                """(Override) Change the text to a different color when the 
                enter event is triggered."""
                if(super().__on_enter__(event)):
                        self.canvas.itemconfig("text" + self.id, 
                                fill=self.hovered_text_color);

        def __on_leave__(self, event):
                """(Override) Change the text to a different color when the 
                leave event is triggered."""
                if(super().__on_leave__(event)):
                        self.canvas.itemconfig("text" + self.id, 
                                fill=self.normal_text_color);

class CanvasSquare(CanvasWidget):
        """A square that responds to mouse click event. This is for the grid
        board."""

        def __init__(self, canvas, x, y, width, normal_color, hovered_color, 
                disabled_color):
                """Initialize the square object."""

                # Initialize super class
                CanvasWidget.__init__(self, canvas);

                # Set color scheme for different states
                self.normal_color = normal_color;
                self.hovered_color = hovered_color;
                self.disabled_color = disabled_color;

                # Create the circle background
                canvas.create_rectangle(x - width/2, y - width/2, x + width/2, 
                        y + width/2, fill=self.normal_color, outline="", 
                        tags=(self.tag_name, "oval" + self.id));

                # Bind events
                self.set_hoverable(True);
                self.set_clickable(True);

        def disable(self):
                """(Override) Change the color when the square is disabled."""
                super().disable();
                self.canvas.itemconfig(self.tag_name, fill=self.disabled_color);

        def enable(self):
                """(Override) Change the color back to normal when the square 
                is disabled."""
                super().enable();
                self.canvas.itemconfig(self.tag_name, fill=self.normal_color);

        def set_temp_color(self, color):
                self.canvas.itemconfig(self.tag_name, fill=color);

class BaseScene(tkinter.Canvas):
        """(Abstract) The base class for all scenes. BaseScene deals with
        general widgets and handles window resizing event."""

        def __init__(self, parent):
                """Initializes the scene."""

                # Initialize the superclass Canvas
                tkinter.Canvas.__init__(self, parent, bg=C_COLOR_BLUE_LIGHT, 
                        width=C_WINDOW_WIDTH, height=C_WINDOW_HEIGHT);

                # Bind the window-resizing event
                self.bind("<Configure>", self.__on_resize__);

                # Set self.width and self.height for later use
                self.width = C_WINDOW_WIDTH; 
                self.height = C_WINDOW_HEIGHT; 

        def __on_resize__(self, event):
                """(Private) This function is called when the window is being
                resied."""

                # Determine the ratio of old width/height to new width/height
                self.wscale = float(event.width)/self.width;
                self.hscale = float(event.height)/self.height;
                self.width = event.width;
                self.height = event.height;

                # Resize the canvas 
                self.config(width=self.width, height=self.height);

                # Rescale all the objects tagged with the "all" tag
                self.scale("all", 0, 0, self.wscale, self.hscale);

        def create_button(self, x, y, button_text, 
                normal_color=C_COLOR_BLUE, hovered_color=C_COLOR_BLUE_DARK, 
                normal_text_color=C_COLOR_BLUE_DARK, 
                hovered_text_color=C_COLOR_BLUE_LIGHT):
                """Creates a button widget and returns it. Note this will
                return a CanvasButton object, not the ID as other standard 
                Tkinter canvas widgets usually returns."""

                return CanvasButton(self, x, y, button_text, 
                        normal_color, hovered_color, 
                        normal_text_color, hovered_text_color);

        def create_square(self, x, y, width,
                normal_color=C_COLOR_BLUE, hovered_color=C_COLOR_BLUE_DARK, 
                disabled_color=C_COLOR_BLUE_LIGHT):
                """Creates a square widget and returns it. Note this will
                return a CanvasSquare object, not the ID as other standard 
                Tkinter canvas widgets usually returns."""

                return CanvasSquare(self, x, y, width,
                        normal_color, hovered_color, disabled_color);

        def create_clickable_label(self, x, y, button_text, 
                normal_color=C_COLOR_BLUE_DARK, hovered_color=C_COLOR_BLUE_LIGHT):
                """Creates a clickable label widget and returns it. Note this
                will return a CanvasClickableLabel object, not the ID as other 
                standard Tkinter canvas widgets usually returns."""

                return CanvasClickableLabel(self, x, y, button_text, 
                        normal_color, hovered_color);

class WelcomeScene(BaseScene):
        """WelcomeScene is the first scene to show when the GUI starts."""

        def __init__(self, parent):
                """Initializes the welcome scene."""

                # Initialize BaseScene
                super().__init__(parent);

                # Create a blue arch at the top of the canvas
                self.create_arc((-64, -368, C_WINDOW_WIDTH + 64, 192), 
                        start=0, extent=-180, fill=C_COLOR_BLUE, outline="");

                try:
                        # From the logo image file create a PhotoImage object 
                        self.logo_image = tkinter.PhotoImage(file="icon.png");
                        # Create the logo image at the center of the canvas
                        logo = self.create_image((C_WINDOW_WIDTH/2, 
                                C_WINDOW_HEIGHT/2 - 96), image=self.logo_image);
                        # From the title image file create a PhotoImage object 
                        self.title_image = tkinter.PhotoImage(file="title.png");
                        # Create the logo image at the center of the canvas
                        title = self.create_image((C_WINDOW_WIDTH/2, 
                                C_WINDOW_HEIGHT/2 + 48), image=self.title_image);
                except: 
                        # An error has been caught when creating the logo image
                        tkinter.messagebox.showerror("Error", "Can't create images.\n" +
                                "Please make sure the res folder is in the same directory" + 
                                " as this script.");

                # Create the Play button
                play_btn = self.create_button(C_WINDOW_WIDTH/2, 
                        C_WINDOW_HEIGHT/2 + 136, "Play");
                play_btn.command = self.__on_play_clicked__;
                # Create the About button
                about_btn = self.create_button(C_WINDOW_WIDTH/2, 
                        C_WINDOW_HEIGHT/2 + 192, "About");
                about_btn.command = self.__on_about_clicked__;

                # Tag all of the drawn widgets for later reference
                self.addtag_all("all");

        def __on_play_clicked__(self):
                """(Private) Switches to the main game scene when the play
                button is clicked."""
                self.pack_forget();
                self.main_game_scene.pack();

        def __on_about_clicked__(self):
                """(Private) Switches to the about scene when the about button 
                is clicked."""
                self.pack_forget();
                self.about_scene.pack();

class AboutScene(BaseScene):
        """AboutScene shows the developer and copyright information."""

        def __init__(self, parent):
                """Initializes the about scene object."""

                # Initialize the base scene
                super().__init__(parent);

                # Create a blue arch at the bottom of the canvas
                self.create_arc((-128, C_WINDOW_HEIGHT - 128, 
                        C_WINDOW_WIDTH + 128, C_WINDOW_HEIGHT + 368), 
                        start=0, extent=180, fill=C_COLOR_BLUE, outline="");

                try:
                        # From the company image file create a PhotoImage object 
                        self.company_image = tkinter.PhotoImage(file="company.png");
                        # Create the logo image on the left of the canvas
                        logo = self.create_image((C_WINDOW_WIDTH/2 - 192, 
                                C_WINDOW_HEIGHT/2 - 48), image=self.company_image);
                        # From the title image file create a PhotoImage object 
                        self.title_image = tkinter.PhotoImage(file="title.png");
                        # Resize the image to make it smaller
                        self.title_image = self.title_image.subsample(2, 2);
                        # Create the logo image at the center of the canvas
                        title = self.create_image((C_WINDOW_WIDTH/2 + 64, 
                                C_WINDOW_HEIGHT/2 - 160), image=self.title_image);
                except: 
                        # An error has been caught when creating the logo image
                        tkinter.messagebox.showerror("Error", "Can't create images.\n" +
                                "Please make sure the res folder is in the same directory" + 
                                " as this script.");
                
                self.create_text(C_WINDOW_WIDTH/2 - 80, C_WINDOW_HEIGHT/2 - 96, 
                        font="Helvetica 14", text="Developed by Mention your name here in the code", 
                        anchor="w", fill=C_COLOR_BLUE_DARK);
                
                link_companyname = self.create_clickable_label(C_WINDOW_WIDTH/2 - 80, 
                        C_WINDOW_HEIGHT/2 - 64, "Link your website url here", 
                        "#0B0080", "#CC2200");
                link_companyname.config(anchor="w");
                link_companyname.command = self.__on_companyname_clicked__;

                self.create_text(C_WINDOW_WIDTH/2 - 80, C_WINDOW_HEIGHT/2, 
                        anchor="w", font="Helvetica 14", fill=C_COLOR_BLUE_DARK, 
                        text="Tic Tac Toe Online in Python is \n" + 
                        "open source under the MIT license");
                
                link_project = self.create_clickable_label(C_WINDOW_WIDTH/2 - 80, 
                        C_WINDOW_HEIGHT/2 + 40, "link your project url here", 
                        "#0B0080", "#CC2200");
                link_project.config(anchor="w");
                link_project.command = self.__on_project_link_clicked__;

                self.create_text(C_WINDOW_WIDTH/2 + 64, C_WINDOW_HEIGHT/2 + 96, 
                        font="Helvetica 16", text="Copyright (c) year of launch(Eg.2015) Your name here", 
                        fill=C_COLOR_BLUE_DARK);
                
                # Create the OK button
                ok_btn = self.create_button(C_WINDOW_WIDTH/2, C_WINDOW_HEIGHT/2 + 160, 
                        "OK", C_COLOR_BLUE_DARK, C_COLOR_BLUE_LIGHT, C_COLOR_BLUE_LIGHT, 
                        C_COLOR_BLUE_DARK);
                ok_btn.command = self.__on_ok_clicked__;

                # Tag all of the drawn widgets for later reference
                self.addtag_all("all");

        def __on_ok_clicked__(self):
                """(Private) Switches back to the welcome scene when the ok button
                is clicked."""
                self.pack_forget();
                self.welcome_scene.pack();

        def __on_companyname_clicked__(self):
                """(Private) Opens companyname.com in the system default browser 
                when the companyname.com link is clicked."""
                webbrowser.open("Your Company Url here");

        def __on_project_link_clicked__(self):
                """(Private) Opens the project link in the system default browser 
                when it is clicked."""
                webbrowser.open("Your company url here");

class MainGameScene(BaseScene):
        """MainGameScene deals with the game logic."""

        def __init__(self, parent):
                """Initializes the main game scene object."""

                # Initialize the base scene
                super().__init__(parent);

                # Initialize instance variables
                self.board_grids_power = 3; # Make it a 3x3 grid board
                self.board_width = 256; # The board is 256x256 wide

                # Create a blue arch at the bottom of the canvas
                self.create_arc((-128, C_WINDOW_HEIGHT - 64, C_WINDOW_WIDTH + 128, 
                        C_WINDOW_HEIGHT + 368), start=0, extent=180, fill=C_COLOR_BLUE, 
                        outline="");

                # Create the return button
                return_btn = self.create_button(C_WINDOW_WIDTH - 128, 32, "Go back");
                return_btn.command = self.__on_return_clicked__;

                self.draw_board();

                # Create the player_self_text
                player_self_text = self.create_text(96, 128, font="Helvetica 16", 
                        fill=C_COLOR_BLUE_DARK, tags=("player_self_text"), anchor="n");
                # Create the player_match_text
                player_match_text = self.create_text(C_WINDOW_WIDTH - 96, 128, 
                        font="Helvetica 16", fill=C_COLOR_BLUE_DARK, 
                        tags=("player_match_text"), anchor="n");

                # Create the notif text
                notif_text = self.create_text(8, C_WINDOW_HEIGHT-8, anchor="sw",
                        font="Helvetica 16", fill=C_COLOR_BLUE_DARK, tags=("notif_text"));

                # Set restart button to None so it won't raise AttributeError
                self.restart_btn = None;

                # Tag all of the drawn widgets for later reference
                self.addtag_all("all");

        def pack(self):
                """(Override) When the scene packs, start the client thread."""
                super().pack();
                # Start a new thread to deal with the client communication
                threading.Thread(target=self.__start_client__).start();

        def draw_board(self, board_line_width = 4):
                """Draws the board at the center of the screen, parameter 
                board_line_width determines the border line width."""

                # Create squares for the grid board
                self.squares = [None] * self.board_grids_power ** 2;
                for i in range(0, self.board_grids_power):
                        for j in range(0, self.board_grids_power):
                                self.squares[i+j*3] = self.create_square(
                                        (C_WINDOW_WIDTH - self.board_width)/2 + 
                                        self.board_width/self.board_grids_power * i + 
                                        self.board_width / self.board_grids_power / 2,
                                        (C_WINDOW_HEIGHT - self.board_width)/2 + 
                                        self.board_width/self.board_grids_power * j + 
                                        self.board_width / self.board_grids_power / 2,
                                        self.board_width / self.board_grids_power);
                                # Disable those squares to make them unclickable
                                self.squares[i+j*3].disable();

                # Draw the border lines
                for i in range(1, self.board_grids_power):
                        # Draw horizontal lines
                        self.create_line((C_WINDOW_WIDTH - self.board_width)/2, 
                                (C_WINDOW_HEIGHT - self.board_width)/2 + 
                                self.board_width/self.board_grids_power * i, 
                                (C_WINDOW_WIDTH + self.board_width)/2, 
                                (C_WINDOW_HEIGHT - self.board_width)/2 + 
                                self.board_width/self.board_grids_power * i, 
                                fill=C_COLOR_BLUE_DARK, width=board_line_width);
                        # Draw vertical lines
                        self.create_line((C_WINDOW_WIDTH - self.board_width)/2 + 
                                self.board_width/self.board_grids_power * i, 
                                (C_WINDOW_HEIGHT - self.board_width)/2, 
                                (C_WINDOW_WIDTH - self.board_width)/2 + 
                                self.board_width/self.board_grids_power * i, 
                                (C_WINDOW_HEIGHT + self.board_width)/2, 
                                fill=C_COLOR_BLUE_DARK, width=board_line_width);

        def __start_client__(self):
                """(Private) Starts the client side."""
                # Initialize the client object
                self.client = TTTClientGameGUI();
                # Gives the client a reference to self 
                self.client.canvas = self;
                try:
                        # Get the host IP address
                        host = socket.gethostbyname('s.ComapanyName.com');
                except:
                        # If can't get the host IP from the domain
                        tkinter.messagebox.showerror("Error", "Failed to get the game "+ 
                                "host address from the web domain.\n" + 
                                "Plase check your connection.");
                        self.__on_return_clicked__();
                        return;
                # Set the notif text
                self.set_notif_text("Connecting to the game server " + host + "...");
                # Connect to the server
                if(self.client.connect(host, "8080")):
                        # If connected to the server
                        # Start the game
                        self.client.start_game();
                        # Close the client
                        self.client.close();

        def __on_return_clicked__(self):
                """(Private) Switches back to the welcome scene when the return 
                button is clicked."""
                # Clear screen
                self.__clear_screen();
                # Set the client to None so the client thread will stop due to error
                self.client.client_socket = None;
                self.client = None;
                # Switch to the welcome scene
                self.pack_forget();
                self.welcome_scene.pack();

        def set_notif_text(self, text):
                """Sets the notification text."""
                self.itemconfig("notif_text", text=text);

        def update_board_content(self, board_string):
                """Redraws the board content with new board_string."""
                if(len(board_string) != self.board_grids_power ** 2):
                        # If board_string is in valid
                        print("The board string should be " + 
                                str(self.board_grids_power ** 2) + " characters long.");
                        # Throw an error
                        raise Exception;

                # Delete everything on the board
                self.delete("board_content");

                p = 16; # Padding

                # Draw the board content
                for i in range(0, self.board_grids_power):
                        for j in range(0, self.board_grids_power):

                                if(board_string[i+j*3] == "O"):
                                        # If this is an "O"
                                        self.create_oval(
                                                (C_WINDOW_WIDTH - self.board_width)/2 + 
                                                self.board_width/self.board_grids_power * i + p,
                                                (C_WINDOW_HEIGHT - self.board_width)/2 + 
                                                self.board_width/self.board_grids_power * j + p,
                                                (C_WINDOW_WIDTH - self.board_width)/2 + 
                                                self.board_width/self.board_grids_power * (i + 1) - p,
                                                (C_WINDOW_HEIGHT - self.board_width)/2 + 
                                                self.board_width/self.board_grids_power * (j + 1) - p,
                                                fill="", outline=C_COLOR_BLUE_DARK, width=4,
                                                tags="board_content");
                                elif(board_string[i+j*3] == "X"):
                                        # If this is an "X"
                                        self.create_line(
                                                (C_WINDOW_WIDTH - self.board_width)/2 + 
                                                self.board_width/self.board_grids_power * i + p,
                                                (C_WINDOW_HEIGHT - self.board_width)/2 + 
                                                self.board_width/self.board_grids_power * j + p,
                                                (C_WINDOW_WIDTH - self.board_width)/2 + 
                                                self.board_width/self.board_grids_power * (i + 1) - p,
                                                (C_WINDOW_HEIGHT - self.board_width)/2 + 
                                                self.board_width/self.board_grids_power * (j + 1) - p,
                                                fill=C_COLOR_BLUE_DARK, width=4,
                                                tags="board_content");
                                        self.create_line(
                                                (C_WINDOW_WIDTH - self.board_width)/2 + 
                                                self.board_width/self.board_grids_power * (i + 1) - p,
                                                (C_WINDOW_HEIGHT - self.board_width)/2 + 
                                                self.board_width/self.board_grids_power * j + p,
                                                (C_WINDOW_WIDTH - self.board_width)/2 + 
                                                self.board_width/self.board_grids_power * i + p,
                                                (C_WINDOW_HEIGHT - self.board_width)/2 + 
                                                self.board_width/self.board_grids_power * (j + 1) - p,
                                                fill=C_COLOR_BLUE_DARK, width=4,
                                                tags="board_content");

        def draw_winning_path(self, winning_path):
                """Marks on the board the path that leads to the win result."""
                # Loop through the board
                for i in range(0, self.board_grids_power ** 2):
                        if str(i) in winning_path: 
                                # If the current item is in the winning path
                                self.squares[i].set_temp_color("#db2631");


        def show_restart(self):
                """Creates a restart button for the user to choose to restart a 
                new game."""
                self.restart_btn = self.create_button(C_WINDOW_WIDTH/2, C_WINDOW_HEIGHT - 32, 
                        "Restart", C_COLOR_BLUE_DARK, C_COLOR_BLUE_LIGHT, C_COLOR_BLUE_LIGHT, 
                        C_COLOR_BLUE_DARK);
                self.restart_btn.command = self.__on_restart_clicked__;

        def __clear_screen(self):
                """(Private) Clears all the existing content from the old game."""
                # Clear everything from the past game
                for i in range(0, self.board_grids_power ** 2):
                        self.squares[i].disable();
                        self.squares[i].set_temp_color(C_COLOR_BLUE_LIGHT);
                self.update_board_content(" " * self.board_grids_power ** 2);
                self.itemconfig("player_self_text", text="");
                self.itemconfig("player_match_text", text="");
                # Delete the button from the scene
                if self.restart_btn is not None:
                        self.restart_btn.delete();
                        self.restart_btn = None;

        def __on_restart_clicked__(self):
                """(Private) Switches back to the welcome scene when the return 
                button is clicked."""
                # Clear screen
                self.__clear_screen();
                # Start a new thread to deal with the client communication
                threading.Thread(target=self.__start_client__).start();


class TTTClientGameGUI(TTTClientGame):
        """The client implemented with GUI."""

        def __connect_failed__(self):
                """(Override) Updates the GUI to notify the user that the connection
                couldn't be established."""
                # Write the notif text
                self.canvas.set_notif_text("Can't connect to the game server.\n" + 
                        "It might be down or blocked by your firewall.");
                # Throw an error and finish the client thread
                raise Exception;

        def __connected__(self):
                """(Override) Updates the GUI to notify the user that the connection
                has been established."""
                self.canvas.set_notif_text("Server connected. \n" +
                        "Waiting for other players to join...");

        def __game_started__(self):
                """(Override) Updates the GUI to notify the user that the game is
                getting started."""
                self.canvas.set_notif_text("Game started. " + 
                        "You are the \"" + self.role + "\"");
                self.canvas.itemconfig("player_self_text", 
                        text="You:\n\nPlayer " + str(self.player_id) + 
                        "\n\nRole: " + self.role);
                self.canvas.itemconfig("player_match_text", 
                        text="Opponent:\n\nPlayer " + str(self.match_id) + 
                        "\n\nRole: " + ("O" if self.role == "X" else "X") );

        def __update_board__(self, command, board_string):
                """(Override) Updates the board."""
                # Print the command-line board for debugging purpose
                super().__update_board__(command, board_string);
                # Draw the GUI board
                self.canvas.update_board_content(board_string);
                if(command == "D"):
                        # If the result is a draw
                        self.canvas.set_notif_text("It's a draw.");
                        # Show the restart button
                        self.canvas.show_restart();
                elif(command == "W"):
                        # If this player wins
                        self.canvas.set_notif_text("You WIN!");
                        # Show the restart button
                        self.canvas.show_restart();
                elif(command == "L"):
                        # If this player loses
                        self.canvas.set_notif_text("You lose.");
                        # Show the restart button
                        self.canvas.show_restart();

        def __player_move__(self, board_string):
                """(Override) Lets the user to make a move and sends it back to the
                server."""

                # Set user making move to be true
                self.making_move = True;

                for i in range(0, self.canvas.board_grids_power ** 2):
                        # Check the board content and see if it's empty
                        if(board_string[i] == " "):
                                # Enable those squares to make them clickable
                                self.canvas.squares[i].enable();
                                # Bind their commands
                                self.canvas.squares[i].command = (lambda self=self, i=i: 
                                        self.__move_made__(i));

                while self.making_move:
                        # Wait until the user has clicked on something
                        pass;

        def __player_wait__(self):
                """(Override) Lets the user know it's waiting for the other player 
                to make a move."""
                # Print the command-line notif for debugging purpose
                super().__player_wait__();
                # Set the notif text on the GUI
                self.canvas.set_notif_text("Waiting for the other player to make a move...");

        def __opponent_move_made__(self, move):
                """(Override) Shows the user the move that the other player has taken."""
                # Print the command-line notif for debugging purpose
                super().__opponent_move_made__(move);
                # Set the notif text on the GUI
                self.canvas.set_notif_text("Your opponent took up number " + str(move) + ".\n"
                        "It's now your turn, please make a move.");

        def __move_made__(self, index):
                """(Private) This function is called when the user clicks on the 
                board to make a move."""

                print("User chose " + str(index + 1));

                for i in range(0, self.canvas.board_grids_power ** 2):
                        # Disable those squares to make them unclickable
                        self.canvas.squares[i].disable();
                        # Remove their commands
                        self.canvas.squares[i].command = None;

                # Send the position back to the server
                self.s_send("i", str(index + 1));

                # Set user making move to be false
                self.making_move = False;

        def __draw_winning_path__(self, winning_path):
                """(Override) Shows to the user the path that has caused the game to 
                win or lose."""
                # Print the command-line winning path for debugging purpose
                super().__draw_winning_path__(winning_path);
                # Draw GUI the winning path
                self.canvas.draw_winning_path(winning_path);
                
# Define the main program
def main():
        # Create a Tkinter object
        root = tkinter.Tk();
        # Set window title
        root.title("Tic Tac Toe");
        # Set window minimun size
        root.minsize(C_WINDOW_MIN_WIDTH, C_WINDOW_MIN_HEIGHT);
        # Set window size
        root.geometry(str(C_WINDOW_WIDTH) + "x" + str(C_WINDOW_HEIGHT));

        try:
                # Set window icon
                root.iconbitmap("res/icon.ico");
        except: 
                # An error has been caught when setting the icon
                # tkinter.messagebox.showerror("Error", "Can't set the window icon.");
                print("Can't set the window icon.");

        # Initialize the welcome scene
        welcome_scene = WelcomeScene(root);
        # Initialize the about scene
        about_scene = AboutScene(root);
        # Initialize the main game scene
        main_game_scene = MainGameScene(root);

        # Give a reference for switching between scenes
        welcome_scene.about_scene = about_scene;
        welcome_scene.main_game_scene = main_game_scene; 
        about_scene.welcome_scene = welcome_scene;
        main_game_scene.welcome_scene = welcome_scene;

        # Start showing the welcome scene
        welcome_scene.pack();
            
        # Main loop
        root.mainloop();

if __name__ == "__main__":
        # If this script is running as a standalone program,
        # start the main program.
        main();

Note: Before executing the code go through it once and change fe things like give your domain name and server link. For example in the code in the place of companyname give your websitefullname or your name.com, in the place of company give name of image you give in your file.

Server: ttt_server.py

# Import the socket module
import socket
# Import multi-threading module
import threading
# Import the time module
import time
# Import command line arguments
from sys import argv
# Import logging
import logging


# Set up logging to file 
logging.basicConfig(level=logging.DEBUG,
        format='[%(asctime)s] %(levelname)s: %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S',
        filename='ttt_server.log');
# Define a Handler which writes INFO messages or higher to the sys.stderr
# This will print all the INFO messages or higer at the same time
console = logging.StreamHandler();
console.setLevel(logging.INFO);
# Add the handler to the root logger
logging.getLogger('').addHandler(console);

class TTTServer:
        """TTTServer deals with networking and communication with the TTTClient."""

        def __init__(self):
                """Initializes the server object with a server socket."""
                # Create a TCP/IP socket
                self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM);

        def bind(self, port_number):
                """Binds the server with the designated port and start listening to
                the binded address."""
                while True:
                        try:
                                # Bind to an address with the designated port
                                # The empty string "" is a symbolic name 
                                # meaning all available interfaces
                                self.server_socket.bind(("", int(port_number)));
                                logging.info("Reserved port " + str(port_number));
                                # Start listening to the binded address
                                self.server_socket.listen(1);
                                logging.info("Listening to port " + str(port_number));
                                # Break the while loop if no error is caught
                                break;
                        except:
                                # Caught an error
                                logging.warning("There is an error when trying to bind " + 
                                        str(port_number));
                                # Ask the user what to do with the error
                                choice = input("[A]bort, [C]hange port, or [R]etry?");
                                if(choice.lower() == "a"):
                                        exit();
                                elif(choice.lower() == "c"):
                                        port_number = input("Please enter the port:");

        def close(self):
                # Close the socket
                self.server_socket.close();

class TTTServerGame(TTTServer):
        """TTTServerGame deals with the game logic on the server side."""

        def __init__(self):
                """Initializes the server game object."""
                TTTServer.__init__(self);

        def start(self):
                """Starts the server and let it accept clients."""
                # Create an array object to store connected players
                self.waiting_players = [];
                # Use a simple lock to synchronize access when matching players
                self.lock_matching = threading.Lock();
                # Start the main loop
                self.__main_loop();

        def __main_loop(self):
                """(Private) The main loop."""
                # Loop to infinitely accept new clients
                while True:
                        # Accept a connection from a client
                        connection, client_address = self.server_socket.accept();
                        logging.info("Received connection from " + str(client_address));

                        # Initialize a new Player object to store all the client's infomation
                        new_player = Player(connection);
                        # Push this new player object into the players array
                        self.waiting_players.append(new_player);

                        try:
                                # Start a new thread to deal with this client
                                threading.Thread(target=self.__client_thread, 
                                        args=(new_player,)).start();
                        except:
                                logging.error("Failed to create thread.");

        def __client_thread(self, player):
                """(Private) This is the client thread."""
                # Wrap the whole client thread with a try and catch so that the 
                # server would not be affected even if a client messes up
                try:
                        # Send the player's ID back to the client
                        player.send("A", str(player.id));
                        # Send the client didn't confirm the message
                        if(player.recv(2, "c") != "1"):
                                # An error happened
                                logging.warning("Client " + str(player.id) + 
                                        " didn't confirm the initial message.");
                                # Finish 
                                return;

                        while player.is_waiting:
                                # If the player is still waiting for another player to join
                                # Try to match this player with other waiting players
                                match_result = self.matching_player(player);

                                if(match_result is None):
                                        # If not matched, wait for a second (to keep CPU usage low) 
                                        time.sleep(1);
                                        # Check if the player is still connected
                                        player.check_connection();
                                else:
                                        # If matched with another player

                                        # Initialize a new Game object to store the game's infomation
                                        new_game = Game();
                                        # Assign both players
                                        new_game.player1 = player;
                                        new_game.player2 = match_result;
                                        # Create an empty string for empty board content
                                        new_game.board_content = list("         ");

                                        try:
                                                # Game starts
                                                new_game.start();
                                        except:
                                                logging.warning("Game between " + str(new_game.player1.id) + 
                                                        " and " + str(new_game.player2.id) + 
                                                        " is finished unexpectedly.");
                                        # End this thread
                                        return;
                except:
                        print("Player " + str(player.id) + " disconnected.");
                finally:
                        # Remove the player from the waiting list
                        self.waiting_players.remove(player);

        def matching_player(self, player):
                """Goes through the players list and try to match the player with 
                another player who is also waiting to play. Returns any matched 
                player if found."""
                # Try acquiring the lock
                self.lock_matching.acquire();
                try:
                        # Loop through each player
                        for p in self.waiting_players:
                                # If another player is found waiting and its not the player itself
                                if(p.is_waiting and p is not player):
                                        # Matched player with p
                                        # Set their match
                                        player.match = p;
                                        p.match = player;
                                        # Set their roles
                                        player.role = "X";
                                        p.role = "O";
                                        # Set the player is not waiting any more
                                        player.is_waiting = False;
                                        p.is_waiting = False;
                                        # Then return the player's ID
                                        return p;
                finally:
                        # Release the lock
                        self.lock_matching.release();
                # Return None if nothing is found
                return None;

class Player:
        """Player class describes a client with connection to the server and
        as a player in the tic tac toe game."""

        # Count the players (for generating unique IDs)
        count = 0;

        def __init__(self, connection):
                """Initialize a player with its connection to the server"""
                # Generate a unique id for this player
                Player.count = Player.count + 1
                self.id = Player.count;
                # Assign the corresponding connection 
                self.connection = connection;
                # Set the player waiting status to True
                self.is_waiting = True; 

        def send(self, command_type, msg):
                """Sends a message to the client with an agreed command type token 
                to ensure the message is delivered safely."""
                # A 1 byte command_type character is put at the front of the message
                # as a communication convention
                try:
                        self.connection.send((command_type + msg).encode());
                except:
                        # If any error occurred, the connection might be lost
                        self.__connection_lost();

        def recv(self, size, expected_type):
                """Receives a packet with specified size from the client and check 
                its integrity by comparing its command type token with the expected
                one."""
                try:
                        msg = self.connection.recv(size).decode();
                        # If received a quit signal from the client
                        if(msg[0] == "q"):
                                # Print why the quit signal
                                logging.info(msg[1:]);
                                # Connection lost
                                self.__connection_lost();
                        # If the message is not the expected type
                        elif(msg[0] != expected_type):
                                # Connection lost
                                self.__connection_lost();
                        # If received an integer from the client
                        elif(msg[0] == "i"):
                                # Return the integer
                                return int(msg[1:]);
                        # In other case
                        else:
                                # Return the message
                                return msg[1:];
                        # Simply return the raw message if anything unexpected happended 
                        # because it shouldn't matter any more
                        return msg;
                except:
                        # If any error occurred, the connection might be lost
                        self.__connection_lost();
                return None;

        def check_connection(self):
                """Sends a meesage to check if the client is still properly connected."""
                # Send the client an echo signal to ask it to repeat back
                self.send("E", "z");
                # Check if "e" gets sent back
                if(self.recv(2, "e") != "z"):
                        # If the client didn't confirm, the connection might be lost
                        self.__connection_lost();

        def send_match_info(self):
                """Sends a the matched information to the client, which includes
                the assigned role and the matched player."""
                # Send to client the assigned role
                self.send("R", self.role);
                # Waiting for client to confirm
                if(self.recv(2,"c") != "2"):
                        self.__connection_lost();
                # Sent to client the matched player's ID
                self.send("I", str(self.match.id));
                # Waiting for client to confirm
                if(self.recv(2,"c") != "3"):
                        self.__connection_lost();

        def __connection_lost(self):
                """(Private) This function will be called when the connection is lost."""
                # This player has lost connection with the server
                logging.warning("Player " + str(self.id) + " connection lost.");
                # Tell the other player that the game is finished
                try:
                        self.match.send("Q", "The other player has lost connection" + 
                                " with the server.\nGame over.");
                except:
                        pass;
                # Raise an error so that the client thread can finish
                raise Exception;

class Game:
        """Game class describes a game with two different players."""

        def start(self):
                """Starts the game."""
                # Send both players the match info
                self.player1.send_match_info();
                self.player2.send_match_info();

                # Print the match info onto screen 
                logging.info("Player " + str(self.player1.id) + 
                        " is matched with player " + str(self.player2.id));

                while True:
                        # Player 1 move
                        if(self.move(self.player1, self.player2)):
                                return;
                        # Player 2 move
                        if(self.move(self.player2, self.player1)):
                                return;

        def move(self, moving_player, waiting_player):
                """Lets a player make a move."""
                # Send both players the current board content
                moving_player.send("B", ("".join(self.board_content)));
                waiting_player.send("B", ("".join(self.board_content)));
                # Let the moving player move, Y stands for yes it's turn to move, 
                # and N stands for no and waiting
                moving_player.send("C", "Y");
                waiting_player.send("C", "N");
                # Receive the move from the moving player
                move = int(moving_player.recv(2, "i"));
                # Send the move to the waiting player
                waiting_player.send("I", str(move));
                # Check if the position is empty
                if(self.board_content[move - 1] == " "):
                        # Write the it into the board
                        self.board_content[move - 1] = moving_player.role;
                else:
                        logging.warning("Player " + str(moving_player.id) + 
                                " is attempting to take a position that's already " + 
                                "been taken.");
                #       # This player is attempting to take a position that's already
                #       # taken. HE IS CHEATING, KILL HIM!
                #       moving_player.send("Q", "Please don't cheat!\n" + 
                #               "You are running a modified client program.");
                #       waiting_player.send("Q", "The other playing is caught" + 
                #               "cheating. You win!");
                #       # Throw an error to finish this game
                #       raise Exception;

                # Check if this will result in a win
                result, winning_path = self.check_winner(moving_player);
                if(result >= 0):
                        # If there is a result
                        # Send back the latest board content
                        moving_player.send("B", ("".join(self.board_content)));
                        waiting_player.send("B", ("".join(self.board_content)));

                        if(result == 0):
                                # If this game ends with a draw
                                # Send the players the result
                                moving_player.send("C", "D");
                                waiting_player.send("C", "D");
                                print("Game between player " + str(self.player1.id) + " and player " 
                                        + str(self.player2.id) + " ends with a draw.");
                                return True;
                        if(result == 1):
                                # If this player wins the game
                                # Send the players the result
                                moving_player.send("C", "W");
                                waiting_player.send("C", "L");
                                # Send the players the winning path
                                moving_player.send("P", winning_path);
                                waiting_player.send("P", winning_path);
                                print("Player " + str(self.player1.id) + " beats player " 
                                        + str(self.player2.id) + " and finishes the game.");
                                return True;
                        return False;

        def check_winner(self, player):
                """Checks if the player wins the game. Returns 1 if wins, 
                0 if it's a draw, -1 if there's no result yet."""
                s = self.board_content;

                # Check columns
                if(len(set([s[0], s[1], s[2], player.role])) == 1):
                        return 1, "012";
                if(len(set([s[3], s[4], s[5], player.role])) == 1):
                        return 1, "345";
                if(len(set([s[6], s[7], s[8], player.role])) == 1):
                        return 1, "678";

                # Check rows
                if(len(set([s[0], s[3], s[6], player.role])) == 1):
                        return 1, "036";
                if(len(set([s[1], s[4], s[7], player.role])) == 1):
                        return 1, "147";
                if(len(set([s[2], s[5], s[8], player.role])) == 1):
                        return 1, "258";

                # Check diagonal
                if(len(set([s[0], s[4], s[8], player.role])) == 1):
                        return 1, "048";
                if(len(set([s[2], s[4], s[6], player.role])) == 1):
                        return 1, "246";

                # If there's no empty position left, draw
                if " " not in s:
                        return 0, "";

                # The result cannot be determined yet
                return -1, "";

# Define the main program
def main():
        # If there are more than 2 arguments 
        if(len(argv) >= 2):
                # Set port number to argument 1
                port_number = argv[1];
        else:
                # Ask the user to input port number
                port_number = input("Please enter the port:");

        try:
                # Initialize the server object
                server = TTTServerGame();
                # Bind the server with the port 
                server.bind(port_number);
                # Start the server
                server.start();
                # Close the server
                server.close();
        except BaseException as e:
                logging.critical("Server critical failure.\n" + str(e));

if __name__ == "__main__":
        # If this script is running as a standalone program,
        # start the main program.
        main();

Client: ttt_client.py

# Import the socket module
import socket
# Import command line arguments
from sys import argv

class TTTClient:
        """TTTClient deals with networking and communication with the TTTServer."""

        def __init__(self):
                """Initializes the client and create a client socket."""
                # Create a TCP/IP socket
                self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM);

        def connect(self, address, port_number):
                """Keeps repeating connecting to the server and returns True if 
                connected successfully."""
                while True:
                        try:
                                print("Connecting to the game server...");
                                # Connection time out 10 seconds
                                self.client_socket.settimeout(10);
                                # Connect to the specified host and port 
                                self.client_socket.connect((address, int(port_number)));
                                # Return True if connected successfully
                                return True;
                        except:
                                # Caught an error
                                print("There is an error when trying to connect to " + 
                                        str(address) + "::" + str(port_number));
                                self.__connect_failed__();
                return False;

        def __connect_failed__(self):
                """(Private) This function will be called when the attempt to connect
                failed. This function might be overridden by the GUI program."""
                # Ask the user what to do with the error
                choice = input("[A]bort, [C]hange address and port, or [R]etry?");
                if(choice.lower() == "a"):
                        exit();
                elif(choice.lower() == "c"):
                        address = input("Please enter the address:");
                        port_number = input("Please enter the port:");

        def s_send(self, command_type, msg):
                """Sends a message to the server with an agreed command type token 
                to ensure the message is delivered safely."""
                # A 1 byte command_type character is put at the front of the message
                # as a communication convention
                try:
                        self.client_socket.send((command_type + msg).encode());
                except:
                        # If any error occurred, the connection might be lost
                        self.__connection_lost();

        def s_recv(self, size, expected_type):
                """Receives a packet with specified size from the server and check 
                its integrity by comparing its command type token with the expected
                one."""
                try:
                        msg = self.client_socket.recv(size).decode();
                        # If received a quit signal from the server
                        if(msg[0] == "Q"):
                                why_quit = "";
                                try:
                                        # Try receiving the whole reason why quit
                                        why_quit = self.client_socket.recv(1024).decode();
                                except:
                                        pass;
                                # Print the resaon
                                print(msg[1:] + why_quit);
                                # Throw an error
                                raise Exception;
                        # If received an echo signal from the server
                        elif(msg[0] == "E"):
                                # Echo the message back to the server
                                self.s_send("e", msg[1:]);
                                # Recursively retrive the desired message
                                return self.s_recv(size, expected_type);
                        # If the command type token is not the expected type
                        elif(msg[0] != expected_type):
                                print("The received command type \"" + msg[0] + "\" does not " + 
                                        "match the expected type \"" + expected_type + "\".");
                                # Connection lost
                                self.__connection_lost();
                        # If received an integer from the server
                        elif(msg[0] == "I"):
                                # Return the integer
                                return int(msg[1:]);
                        # In other case
                        else:
                                # Return the message
                                return msg[1:];
                        # Simply return the raw message if anything unexpected happended 
                        # because it shouldn't matter any more
                        return msg;
                except:
                        # If any error occurred, the connection mi
                    

Related Solutions

Write a program that plays tic-tac-toe. The tic-tac-toe game is played on a 3 × 3...
Write a program that plays tic-tac-toe. The tic-tac-toe game is played on a 3 × 3 grid as shown below: The game is played by two players, who take turns. The first player marks moves with a circle, the second with a cross. The player who has formed a horizontal, vertical, or diagonal sequence of three marks wins. Your program should draw the game board, ask the user for the coordinates of the next mark (their move), change the players...
Python Code Needed Two-Player, Two-Dimensional Tic-Tac-Toe Write a script to play two-dimensional Tic-Tac-Toe between two human...
Python Code Needed Two-Player, Two-Dimensional Tic-Tac-Toe Write a script to play two-dimensional Tic-Tac-Toe between two human players who alternate entering their moves on the same computer. Create a 3-by-3 two-dimensional array. Each player indicates their moves by entering a pair of numbers representing the row and column indices of the square in which they want to place their mark, either an 'X' or an 'O'. When the first player moves, place an 'X' in the specified square. When the second...
please create a tic tac toe game with python using only graphics.py library
please create a tic tac toe game with python using only graphics.py library
In Python: Please complete the following two tasks in Tic Tac Toe: 1. Allow the user...
In Python: Please complete the following two tasks in Tic Tac Toe: 1. Allow the user to choose heads/tails to see if the user goes first or the computer and alter your code accordingly. 2. Allow the user to play again. Add a simple strategy for the AI to play against the user.
If anyone can please write a code for a 5x5 tic tac toe game in matlab...
If anyone can please write a code for a 5x5 tic tac toe game in matlab I would greatly appreciate it. Its extra credit. PLEASE HELP ME :(
Write a class (and a client class to test it) that encapsulates a tic-tac-toe board. A...
Write a class (and a client class to test it) that encapsulates a tic-tac-toe board. A tic-tac-toe board looks like a table of three rows and three columns partially or completely filled with the characters X and O. At any point, a cell of that table could be empty or could contain an X or an O. You should have one instance variable, a two-dimensional array of values representing the tic-tac-toe board. This game should involve one human player vs....
If you were to write a game of tic-tac-toe, you may store the representation of the...
If you were to write a game of tic-tac-toe, you may store the representation of the game board as a two dimensional list such as   [['X', '', 'X'], ['O', 'X', ''], ['', 'O', 'X']] where each sublist is a row in the board.   Empty strings ('') denote a space that does not yet have a value. Assuming this representation, write functions (contained in the same file) that do the following: a) Create a new empty tic-tac-toe board. This function should...
For this assignment, you will write a tic-tac-toe application in HTML and JavaScript, using an HTML...
For this assignment, you will write a tic-tac-toe application in HTML and JavaScript, using an HTML <canvas> tag. The game will be played "hot seat" where players take turns using the same device. Requirements: The canvas should be 600px tall and wide, with the gameplay area occupying most of the canvas. The X's and O's may be drawn using polygons or large-font text The grid should be drawn using polygons, specifically long, thin rectangles Before & between games, the canvas...
Perk Company produces three products: Tic, Tac, and Toe. Tic requires 90 machine setups, Tac requires...
Perk Company produces three products: Tic, Tac, and Toe. Tic requires 90 machine setups, Tac requires 80 setups, and Toe requires 330 setups. Berk has identified an activity cost pool with allocated overhead of $18,000 for which the cost driver is machine setups. How much overhead is assigned to the Tic product?
How to make tic tac toe game in javascript with vue.js
How to make tic tac toe game in javascript with vue.js
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT