Created
November 12, 2022 18:48
-
-
Save bipinkrish/c0515151e7b5b780ced81bac9539ed16 to your computer and use it in GitHub Desktop.
TicTacToe v/s AI or with 2 Players
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random | |
from os import system, name | |
############################################################################ | |
# Clear function | |
def clear(): | |
# for windows | |
if name == 'nt': | |
_ = system('cls') | |
# for mac and linux(here, os.name is 'posix') | |
else: | |
_ = system('clear') | |
########################################################################### | |
# AI | |
# Random | |
def selectRandom(board): | |
ln = len(board) | |
r = random.randrange(0,ln) | |
return board[r] | |
# To check if one of the following patterns are true; then the respective player has won | |
def win_check(board, choice): | |
#HORIZONTAL CHECK; | |
return ( | |
( board[1] == choice and board[2] == choice and board[3] == choice ) | |
or ( board[4] == choice and board[5] == choice and board[6] == choice ) | |
or ( board[7] == choice and board[8] == choice and board[9] == choice ) | |
#VERTICAL CHECK; | |
or ( board[1] == choice and board[4] == choice and board[7] == choice ) | |
or ( board[2] == choice and board[5] == choice and board[8] == choice ) | |
or ( board[3] == choice and board[6] == choice and board[9] == choice ) | |
#DIAGONAL CHECK; | |
or ( board[1] == choice and board[5] == choice and board[9] == choice ) | |
or ( board[3] == choice and board[5] == choice and board[7] == choice ) ) | |
# Getting Board (like keypad) | |
def getboard(data,order): | |
board = ["N"] | |
for i in range(9): | |
temp = data[order[i]] | |
if temp == "1": | |
board.append("X") | |
elif temp == "2": | |
board.append("O") | |
else: | |
board.append(" ") | |
return board | |
# AI Function | |
def CompAI(board): | |
position = 0 | |
possibilities = [x for x, letter in enumerate(board) if letter == ' ' and x != 0] | |
# including both X and O, since if computer will win, he will place a choice there, but if the component will win --> we have to block that move | |
for let in ['O', 'X']: | |
for i in possibilities: | |
# Creating a copy of the board everytime, placing the move and checking if it wins; | |
# Creating a copy like this and not this boardCopy = board, since changes to boardCopy changes the original board; | |
boardCopy = board[:] | |
boardCopy[i] = let | |
if(win_check(boardCopy, let)): | |
position = i | |
return position | |
openCorners = [x for x in possibilities if x in [1, 3, 7, 9]] | |
if len(openCorners) > 0: | |
position = selectRandom(openCorners) | |
return position | |
if 5 in possibilities: | |
position = 5 | |
return position | |
openEdges = [x for x in possibilities if x in [2, 4, 6, 8]] | |
if len(openEdges) > 0: | |
position = selectRandom(openEdges) | |
return position | |
# Managing in b/w | |
def getAI(data): | |
order = [6,7,8,3,4,5,0,1,2] | |
board = getboard(data,order) | |
pos = CompAI(board) | |
if pos != None: | |
return order[pos-1] | |
########################################################################### | |
# Priniting and Taking Input | |
# Printing | |
def printtable(data): | |
clear() | |
print() | |
for i in range(9): | |
if data[i] == "1": | |
print(" X ",end="") | |
elif data[i] == "2": | |
print(" O ",end ="") | |
else: | |
print("[ ]",end="") | |
if (i+1)%3 == 0: | |
print() | |
else: | |
print(" ",end="") | |
# Taking Input | |
def takeinput(chance,data): | |
print() | |
if chance: | |
pos = input("Player 1's Chance (X) : ") | |
mark = "1" | |
else: | |
pos = input("Player 2's Chance (O) : ") | |
mark = "2" | |
try : pos = int(pos) | |
except: pos = 0 | |
pos -= 1 | |
if (pos < 9) and (pos > -1) and (data[pos] == "0"): | |
return pos, mark, not chance | |
else: | |
printtable(data) | |
print("\nInvalid Positon, Try Again") | |
return takeinput(chance, data) | |
########################################################################### | |
# Checking for Winner | |
# Converting String into Matrix | |
def convert(data): | |
datalist = [] | |
temp = [] | |
for i in range(9): | |
if data[i] == '1': | |
temp.append("X") | |
elif data[i] == "2": | |
temp.append("O") | |
else: | |
temp.append(" ") | |
if (i+1)%3 == 0: | |
datalist.append(temp) | |
temp = [] | |
return datalist | |
# Transposing the Matrix | |
def transpose(matrix): | |
rows = len(matrix) | |
columns = len(matrix[0]) | |
matrix_T = [] | |
for j in range(columns): | |
row = [] | |
for i in range(rows): | |
row.append(matrix[i][j]) | |
matrix_T.append(row) | |
return matrix_T | |
# (part of CheckWin) | |
def checkRows(board): | |
for row in board: | |
if len(set(row)) == 1: | |
return row[0] | |
return 0 | |
# (part of CheckWin) | |
def checkDiagonals(board): | |
if len(set([board[i][i] for i in range(len(board))])) == 1: | |
return board[0][0] | |
if len(set([board[i][len(board)-i-1] for i in range(len(board))])) == 1: | |
return board[0][len(board)-1] | |
return 0 | |
# Checking Winner | |
def checkWin(board): | |
for newBoard in [board, transpose(board)]: | |
result = checkRows(newBoard) | |
if result: | |
return result | |
return checkDiagonals(board) | |
# in b/w | |
def check(data): | |
res = checkWin(convert(data)) | |
if res == " " or res == 0: | |
return False,0 | |
else: | |
if res == "X": | |
return True,1 | |
elif res == "O": | |
return True,2 | |
# Decalring Winner if found | |
def decalre(data): | |
result = check(data) | |
if result[0]: | |
print() | |
if result[1] == 1: | |
print("Player 1 Won (X)") | |
else: | |
print("Player 2 Won (O)") | |
print() | |
exit(1) | |
########################################################################### | |
# Strarting Point | |
# Start Function | |
def start(): | |
clear() | |
while 1: | |
try: | |
players = int(input("Number of Players -- 1 (P v/s Ai) or 2 (P v/s P) : ")) | |
if players not in [1,2]: raise | |
else: break | |
except: print("Invalid, Try Again") | |
if players == 2: ai = False | |
else: ai = True | |
data = "000000000" | |
chance = random.choice((False, True)) | |
if ai: print("\nPlayer 1 : You\nPlayer 2 : AI\n") | |
else: print() | |
print("You need to enter numbers from 1 - 9 to select the positions") | |
if chance: print("Player 1 will start this Game") | |
else: print("Player 2 will start this Game") | |
input("Click any Button to Start...") | |
printtable(data) | |
for i in range(9): | |
if ai and (not chance): | |
pos = getAI(data) | |
mark = "2" | |
chance = True | |
else: pos,mark,chance = takeinput(chance,data) | |
data = data[:pos] + mark + data[pos+1:] | |
printtable(data) | |
decalre(data) | |
print("\nDraw") | |
# Calling Start Function | |
start() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment